C# For-in-Foreach循环性能改进

C# For-in-Foreach循环性能改进,c#,performance,for-loop,foreach,C#,Performance,For Loop,Foreach,我有一个包含2M个条目的db表 我的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 = _xReposit

我有一个包含2M个条目的db表

我的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);
        }
    }
}
var query=\uxrepository.TableNoTracking;
var xNodes=query.ToList()
var n=新的xWeights();
foreach(xNodes中的变量x)
{
对于(var i=0;i10e-12?Δφ/Δψ:Math.Cos(φ1);//E-W课程产生0/0的问题
//如果经度超过180°,则在反经线上取较短的直角线:
如果(数学Abs(Δλ)>数学PI)Δλ=Δλ>0?-(2*Math.PI-Δλ):(2*Math.PI+Δλ);
var dist=(数学Sqrt(Δφ*Δφ+q*q*Δλ*Δλ))*R;
n、 x_Id=x.Id;
n、 Tox=xNodes[i].Id;
n、 距离=距离;
_xweightsrespository.插入(n);
}
}
}

我的问题是;我每分钟获得大约35k条记录,因此每小时将有210万条记录。这要花很长时间才能完成。有什么办法可以提高性能吗?

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

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

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

查看SQL空间索引。我猜你的答案就是这个方向:
问题不在于此功能,而在于您试图实现的功能

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

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

查看SQL空间索引。我猜你的答案就是这个方向:

是的。停止一行一行地计算。您应该直接在t-sql中执行此操作。然后想想你需要对一列做什么,而不是对每一行做什么。但是你说你有200万行,需要一个小时才能完成。这并不是永远的,除非这是在点击按钮或应用程序中的某个东西之后我不知道如何在sql中实现它。不幸的是,它正在应用中。是的,我有2M条记录,这将与2M条记录配对。所以这样做几乎需要200万小时:)你真有趣。您抱怨每个内部循环执行一个insert操作需要很长时间?当然要花很长时间,你期待什么?@Tseng你有什么建议?添加到列表并以这种方式插入?@BulutKartal您使用的是LINQ到SQL还是实体框架6或EF核心?您是否将范围添加到
DBSet
?见答案。是的。停止一行一行地计算。您应该直接在t-sql中执行此操作。然后想想你需要对一列做什么,而不是对每一行做什么。但是你说你有200万行,需要一个小时才能完成。这并不是永远的,除非这是在点击按钮或应用程序中的某个东西之后我不知道如何在sql中实现它。不幸的是,它正在应用中。是的,我有2M条记录,这将与2M条记录配对。所以这样做几乎需要200万小时:)你真有趣。您抱怨每个内部循环执行一个insert操作需要很长时间?当然要花很长时间,你期待什么?@Tseng你有什么建议?添加到列表并以这种方式插入?@BulutKartal您使用的是LINQ到SQL还是实体框架6或EF核心?您是否将范围添加到
DBSet
?看答案。我想我会采用非加权进近:)我想我会采用非加权进近:)