【问题标题】:Improve performance when sorting and reading JSON from file C#从文件 C# 排序和读取 JSON 时提高性能
【发布时间】:2019-02-14 10:01:59
【问题描述】:

我有一个 JSON 文件,其中包含大约 20k 行代码,必须读取、排序并保存到数据库中。我已经为它编写了代码,它按照预期的方式工作,但我的问题是它需要大约 10 分钟。因此,我想知道是否有人知道可以做些什么来提高性能?

json:

{
    "Number": 123456,
    "Area": "NE01"
},
{
    "Number": 123457,
    "Area": "NE01"
},

等等……

C#:

dynamic json = JsonConvert.DeserializeObject(File.ReadAllText(path, Encoding.UTF8));

foreach (var obj in json)
{
    if (obj.Area == "NE01")
    {
        var o = new object
        {
            Number = obj.Number,
        };
        db.Entity.Add(obj);
        continue;
    }

    if (obj.Area == "NE02")
    {
        var o = new object
        {
            Number = obj.Number,
        };
        db.Entity.Add(obj);
        continue;
    }

    if (obj.Area == "NE03")
    {
        var o= new object
        {
            Number = obj.Number,
        };
        db.Entity.Add(obj);
        continue;
    }

    if ( obj.Area== "NE04")
    {
        var o = new object
        {
            Number = obj.Number
        };
        db.Entity.Add(obj);
        continue;
    }
}

db.SaveChanges();

为了更清楚,面积有四个不同的值。根据值的不同,数字将有一个指向该区域的外键。不幸的是,我不允许更改底层数据库中的任何内容。 如果我需要提供更多信息,请告诉我。

【问题讨论】:

  • 您是否添加了计时以查看时间的去向?有 4 个时间点,作为开始:File.ReadAllTextJsonConvert.DeserializeObjectforeach 循环,最后是 SaveChanges。直到你知道时间花在了哪里:你不能开始让它更快。
  • 可能会看看批量操作 - EF 不支持它。如果 SaveChanges 很慢
  • 这不是有效的 Json。
  • @SaniSinghHuttunen 我想我们可以推断它是来自 JSON 的 extract,大概来自 JSON 数组;我不确定这是我们需要挂断的事情......
  • 回显@Vladimir:如果all 你在这里做的是插入,那么SqlBulkCopy 可能是你最好的选择。有一些有趣的方法可以做到这一点,但也许最方便(如果您有一个看起来像表格的T 中的List<T>)是使用FastMember.ObjectReader 在此处查找bcpgithub.com/mgravell/fast-member

标签: c# .net json performance deserialization


【解决方案1】:

使用 EntityFramework.Utilities 您可以使用 Bulk Insert 来加快插入速度。

类似:

public class Data
{
  public int Number { get; set; }
  public string Area { get; set; }
}

var objects = JsonConvert.DeserializeObject<List<Data>>(File.ReadAllText(path, Encoding.UTF8))
  .Select(d => new object { Number = d.Number })
  .ToList();

EFBatchOperation.For(db, db.Entity).InsertAll(objects);

免责声明:代码未经测试。

【讨论】:

    【解决方案2】:

    只有通过使用 AddRange,我才能将时间缩短到一分钟多一点。这对我的目的来说已经足够好了。

    【讨论】:

      猜你喜欢
      • 2019-03-21
      • 1970-01-01
      • 1970-01-01
      • 2020-12-09
      • 1970-01-01
      • 1970-01-01
      • 2018-02-04
      • 2016-09-05
      • 1970-01-01
      相关资源
      最近更新 更多