【问题标题】:For Loop in Foreach Loop Performance ImprovementForeach 循环中的 For 循环性能改进
【发布时间】:2018-03-30 19:14:27
【问题描述】:

我有一个包含 2M 条目的数据库表

我的 XPositions 表结构是

Id - int
FID - int
CoordinateQue - int
Latitude - float
Longitude - float

每一行代表一个标记位置,我需要计算每个坐标之间的距离并保存到另一个表中。

我的 xWeights 表结构是;

Id - int
x_Id - int
Tox - int
Distance - decimal(18,8)

到目前为止我的工作代码是

var query = _xRepository.TableNoTracking;
var xNodes = query.ToList()
var n = new xWeights();

foreach (var x in xNodes)
{
    for (var i = 0; i < xNodes.Count; i++)
    {
        if(x.Id == xNodes[i].Id)
        {
            //Do nothing - Same Node
        }
        else
        { 
        var R = 6378137; 
        var φ1 = (Math.PI / 180) * x.Latitude;
        var φ2 = (Math.PI / 180) * xNodes[i].Latitude;
        var Δφ = (xNodes[i].Latitude - x.Latitude) * (Math.PI / 180);
        var Δλ = (xNodes[i].Longitude - x.Longitude) * (Math.PI / 180);
        var Δψ = Math.Log(Math.Tan(Math.PI / 4 + φ2 / 2) / Math.Tan(Math.PI / 4 + φ1 / 2));
        var q = Math.Abs(Δψ) > 10e-12 ? Δφ / Δψ : Math.Cos(φ1); // E-W course creates problem with 0/0
        // if Longitude over 180° take shorter rhumb line across the anti-meridian:
        if (Math.Abs(Δλ) > Math.PI) Δλ = Δλ > 0 ? -(2 * Math.PI - Δλ) : (2 * Math.PI + Δλ);
        var dist = (Math.Sqrt(Δφ * Δφ + q * q * Δλ * Δλ)) * R;

        n.x_Id = x.Id;
        n.Tox = xNodes[i].Id;
        n.Distance = dist;

            _xWeightsRepository.Insert(n);
        }
    }
}

我的问题是;我每分钟大约有 35k 条记录,所以每小时将有 210 万条记录。这将需要很长时间才能完成。任何想法如何提高性能?

【问题讨论】:

  • 是的。通过痛苦的行停止计算行。您应该直接在 t-sql 中执行此操作。然后想想你需要对一列做什么,而不是你想对每一行做什么。但是你说你有 200 万行,需要一个小时才能完成。除非这是在按钮单击或应用程序中的某些内容之后,否则这不是永远的。 ;)
  • 我不知道如何在 sql 中做到这一点。不幸的是,它正在申请中。是的,我有 2M 条记录,它们将与 2M 条记录配对。所以这种方式几乎需要 200 万小时 :)
  • 你很有趣。当您为每个内部循环执行 ONE 插入操作时,您抱怨它需要很长时间?当然它需要永远,你期待什么?
  • @Tseng 你有什么建议?添加到列表并以这种方式插入?
  • @BulutKartal 您使用的是 LINQ to SQL 还是 Entity Framework 6 或 EF Core?你对DBSet 做了AddRange 吗?请参阅this 答案。

标签: c# performance for-loop foreach


【解决方案1】:

问题不在于此功能,而在于您要实现的目标。

您正在尝试将每个 from-to 组合插入 _xWeightsRepository。如果有 200 万个节点,那就意味着 4000 亿个权重。

如果您可以在每个 CPU 时钟周期插入一个权重(这比您实际希望达到的速度快几个数量级),那么您仍将等待十年或二十年。

查看 SQL 空间索引。我会猜测你的答案就在那个方向: https://docs.microsoft.com/en-us/sql/t-sql/statements/create-spatial-index-transact-sql

【讨论】:

  • 我想我会采用未加权的方法:)
猜你喜欢
  • 2014-04-19
  • 1970-01-01
  • 2017-07-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-08-28
  • 2018-01-14
  • 2015-03-21
相关资源
最近更新 更多