Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/337.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 大foreach循环变慢_C# - Fatal编程技术网

C# 大foreach循环变慢

C# 大foreach循环变慢,c#,C#,首先,对不起我的英语,它不是我的主要语言。第二,我会尽我所能解释我自己,但如果有什么不清楚的地方,我可以提供任何细节。我有点经验不足,让我们开始吧 我有一个大的foreach循环,包含39k个元素 foreach (Busqueda.CodDesCIE elemResult in result.listaCodDesCIE) { timer.Restart(); elemResultExterno = new

首先,对不起我的英语,它不是我的主要语言。第二,我会尽我所能解释我自己,但如果有什么不清楚的地方,我可以提供任何细节。我有点经验不足,让我们开始吧

我有一个大的foreach循环,包含39k个元素

foreach (Busqueda.CodDesCIE elemResult in result.listaCodDesCIE)
            {
                timer.Restart();
                elemResultExterno = new getCodBusquedaResponse.ResultadoBusquedaResponse(elemResult.IdBuzon_Detalle, elemResult.Orden, elemResult.TipoAcierto, elemResult.ObjCIE10.Codigo, elemResult.ObjCIE10.Deslarga, elemResult.Cie10Adic1, elemResult.Cie10Adic2);
                listaResult.Add(elemResultExterno);
                param += " IdBuzon_Detalle:" + elemResultExterno.IdBuzonDetalle + " Orden:" + elemResultExterno.Orden + " TipoAcierto:" + elemResultExterno.TipoAcierto + " Codigo:" + elemResultExterno.Codigo + " Descripcion:" + elemResultExterno.Descripcion + " CodAdic1:" + elemResultExterno.CodAdic1 + " CodAdic2:" + elemResult.Cie10Adic2 + "\r\n";
                timer.Stop();
                Logger.Current.InfoLog("timerPartial: " + timer.ElapsedMilliseconds.ToString(), "itemNumber", orden.ToString());

                orden++;
            }
新的getCodBusquedaResponse.ResultadoBusquedaResponse()

问题是,每次迭代,第一次不到0毫秒。。。6k或更多元素,但迭代时间从该点开始增长,在最终迭代中达到5ms。局部地,我也看到一些偷看(如果你这样叫它“高点”的话,我不知道),迭代可能需要80毫秒或100毫秒

我想知道,为什么时间一直在增长,如果这是正常的,如果它是容易避免的…以及一些帮助/解释如何优化这段代码

日志:时间单位为毫秒

[INFO] - itemNumber.2() - timerPartial: 0
[INFO] - itemNumber.7666() - timerPartial: 0
[INFO] - itemNumber.7667() - timerPartial: 1
[INFO] - itemNumber.7725() - timerPartial: 81
[INFO] - itemNumber.23579() - timerPartial: 3
[INFO] - itemNumber.24356() - timerPartial: 101
[INFO] - itemNumber.28144() - timerPartial: 5
[INFO] - itemNumber.29201() - timerPartial: 6
[INFO] - itemNumber.33997() - timerPartial: 5
[INFO] - itemNumber.33998() - timerPartial: 6
[INFO] - itemNumber.38547() - timerPartial: 80
foreachLoop.() - timerTotal: 239389
非常感谢

编辑:
列表结果

编辑2:你们中的许多人似乎都指出了问题的症结所在。这段代码不是100%我的,所以不确定这是否真的需要,我会尝试一些你的建议,甚至评论这行,并给出一些反馈,谢谢

编辑3:哇。注释了字符串行:foreachLoop.()-timerTotal:20343

我不知道这个问题。现在,这将使它。当然,我也会尝试卡宾编码器的建议。如果这也有帮助的话,那太好了,我可以节省的任何时间都会受到欢迎


非常感谢。

我注意到一件不好的事情是,您添加了
param
字符串变量。这将在循环中创建大量丢弃对象。而是使用字符串生成器

StringBuilder builder = new StringBuilder()
foreach (Busqueda.CodDesCIE elemResult in result.listaCodDesCIE)
{
   ..
    builder.Append(" IdBuzon_Detalle:").Append( elemResultExterno.IdBuzonDetalle);//etc.....
}
param = builder.ToString();

我注意到一件不好的事情是,您添加了
param
string变量。这将在循环中创建大量丢弃对象。而是使用字符串生成器

StringBuilder builder = new StringBuilder()
foreach (Busqueda.CodDesCIE elemResult in result.listaCodDesCIE)
{
   ..
    builder.Append(" IdBuzon_Detalle:").Append( elemResultExterno.IdBuzonDetalle);//etc.....
}
param = builder.ToString();

CarbineCoder的答案是一个明显的优化

另一个是:

var listaResult= new List<getCodBusquedaResponse.ResultadoBusquedaResponse>(YOUR_EXPECTED_CAPACITY);
var listaResult=新列表(您的预期容量);
试试这些。
如果他们不工作。更新您的问题,使其不包含我们未知的方法。

CarbineCoder的答案是一个明显的优化

另一个是:

var listaResult= new List<getCodBusquedaResponse.ResultadoBusquedaResponse>(YOUR_EXPECTED_CAPACITY);
var listaResult=新列表(您的预期容量);
试试这些。
如果他们不工作。更新您的问题,使其不包含我们不知道的方法。

您应该发布
getCodBusquedaResponse.ResultadoBusquedaResponse
代码,因为问题似乎一定在那里,因为您正在添加一个不断增长的字符串,最有可能的峰值是垃圾收集器启动,什么类型的列表结果是
listaResult
?此外,您最可能使用的
计时器
不够精确,无法给出准确的计时结果。不管怎样,堆栈溢出不是“优化我的代码”,您需要确定缓慢的部分,并询问如何改进这些部分的具体问题。您继续连接字符串
param
-这是不好的,因为字符串是不可变的,所以会在内存中创建一个新字符串,并保留两个值。如果该循环运行了39k次,那么内存中可能会存储39k个字符串(取决于垃圾收集器运行的时间)。这可能会导致性能问题。关于这是由于堆上的收集压力造成的建议似乎是合理的,但您应该使用良好的工程实践。找一个内存分析器,确定你产生了多少内存压力,以及“空间”方面的压力是否是你在“时间”方面观察到的结果。@GediminasMasaitis:因为如果性能费用是由垃圾收集器造成的,那么就不会有需要调优的代码热点;这个问题必须通过找到分配的热点并加以解决来解决。如果发现内存使用情况良好且GCs不是问题的原因,那么您已经证伪了假设,可以继续下一个假设,并选择工具证伪或确认它。您应该发布您的
getCodBusquedaResponse.ResultadObjusQuedaResponse
代码,问题似乎就在这里,因为您正在添加一个不断增长的字符串,最有可能出现的峰值是垃圾收集器的启动,以及
listaResult
是什么类型?此外,您最可能使用的
计时器
不够精确,无法给出准确的计时结果。不管怎样,堆栈溢出不是“优化我的代码”,您需要确定缓慢的部分,并询问如何改进这些部分的具体问题。您继续连接字符串
param
-这是不好的,因为字符串是不可变的,所以会在内存中创建一个新字符串,并保留两个值。如果该循环运行了39k次,那么内存中可能会存储39k个字符串(取决于垃圾收集器运行的时间)。这可能会导致性能问题。关于这是由于堆上的收集压力造成的建议似乎是合理的,但您应该使用良好的工程实践。找一个内存分析器,确定你产生了多少内存压力,以及“空间”方面的压力是否是你在“时间”方面观察到的结果。@GediminasMasaitis:因为如果性能费用是由垃圾收集器造成的,那么就不会有需要调优的代码热点;这个问题必须通过找到分配的热点并加以解决来解决。如果结果表明内存使用情况良好,GCs不是问题的原因,那么你已经证伪了假设,可以继续下一个假设,并选择一个工具证伪或确认它。我们不要对这样的问题进行随机优化。OP应该完全能够自己识别这个问题,然后找到这个确切的建议,就像之前几千次建议的那样。他需要做的不仅仅是引入
StringBuilder
来优化这个代码…尝试了这个:foreachLoop。()-timerTotal:26532。整个过程增加6秒,acce