C# 更有效地加载列表

C# 更有效地加载列表,c#,performance,lambda,parallel-extensions,C#,Performance,Lambda,Parallel Extensions,我的任务是更新一些遗留代码,并且确实需要减少部分代码的运行时间。下面的列表经常被加载。我已经设法将时间从大约一分钟缩短到大约十五秒,但它确实需要进一步缩短。下面几行代码工作得相当好,但我正试图从中挤出我能挤出的一切 List<MyObject> _moList = new List<MyObject>(DB.GetAll(queryString, parameters, MyObject.Extract)); _moList.AsParallel().ForAll(s =

我的任务是更新一些遗留代码,并且确实需要减少部分代码的运行时间。下面的列表经常被加载。我已经设法将时间从大约一分钟缩短到大约十五秒,但它确实需要进一步缩短。下面几行代码工作得相当好,但我正试图从中挤出我能挤出的一切

List<MyObject> _moList = new List<MyObject>(DB.GetAll(queryString, parameters, MyObject.Extract));
_moList.AsParallel().ForAll(s => s.RelativeCost = GetRelativeCost(s));
List\u moList=新列表(DB.GetAll(queryString,parameters,MyObject.Extract));
_moList.AsParallel().ForAll(s=>s.RelativeCost=GetRelativeCost(s));
所以我有几个问题。首先,是否有可能将这两条线合并为一条线,如果有,如何合并?第二,这样做会提高性能吗

有些不确定的项目是MyObject大约有40个属性(不确定这是否相关),而GetRelativeCost在时间/cpu周期方面有点昂贵(因此并行运行)

任何帮助都将不胜感激


另外,我也在从其他角度工作,特别是试图降低GetRelativeCost的“成本”,但我需要得到我能从中得到的每个周期,以使其为用户所接受。

您可以通过删除变量并在新的结果上调用Asparel,将它们组合成一行

(new List<MyObject>(DB.GetAll(queryString, parameters, MyObject.Extract))).AsParallel().ForAll(s => s.RelativeCost = GetRelativeCost(s));
(新列表(DB.GetAll(queryString,parameters,MyObject.Extract))).AsParallel().ForAll(s=>s.RelativeCost=GetRelativeCost(s));
但是,不要期望这会提高代码的性能

  • 你运行了探查器吗?您确定正在优化瓶颈吗
  • 为什么您试图优化列表处理而不是
    GetRelativeCost
  • 什么是
    DB.GetAll
    ?你确定它以最佳方式工作吗
  • 我是否假设MyObject.Extract是某种对象函数?你确定它是最优的吗
  • 为什么在加载列表时执行
    GetRelativeCost
    ?推迟执行难道没有意义吗
  • 更多关于最后一点。如果你的
    GetRelativeCost
    有一些副作用,你最好还是去掉它们,因为这违反了DRY原则。如果没有,您可能希望重写
    RelativeCost
    ,以允许延迟初始化,如

    private int? _relativeCost
    public int RelativeCost {
        get {
           if  (!_relativeCost.HasValue)
                _relativeCost = GetRelativeCost();
           return _relativeCost;
        }
    }
    
    通过这种方式,您可以将
    GetRelativeCost
    的执行延迟到真正需要时。通过这种方式,您可以通过以下方式进行优化:不计算真正不需要设置的实体的
    GetRelativeCost
    ,以及通过延迟
    GetRelativeCost
    中代价高昂的计算来加速特定的代码段


    总而言之:运行探查器,确定瓶颈,优化瓶颈。如果瓶颈出现在
    GetRelativeCost
    中,请尝试如上所述将其设置为惰性。

    看起来您要访问数据库……您是否分析了查询以查看是否可以加快查询速度?您是否希望提高平均性能(在应用程序的反生命周期内)或每次运行的最坏情况下的性能?如果是前者,您可以尝试每次缓存结果,并在重新加载之前测试源数据是否发生更改。为什么要使用
    AsParallel
    而不是
    Parallel。ForEach
    ?kzhen-是的,Pieter-是前者,我会看看是否有办法做到这一点Zaid-没有理由。有什么理由用一个代替另一个吗。是的,好几次。我还试图优化得到相对成本3。这是无法控制的。它是DB.GetAll指的是我没有源代码的第三方程序集。要删除所有引用,需要对代码进行重大重写。4.我愿意接受建议。见下文。a-下一行是
    \u objectCache=new List(\u moList.Select(s=>newmyobjectdisplayer))然后我必须通过另一个对象访问该对象。将其移动到列表加载可以减少我大约10%的时间。b-MyObject是更大构造的一部分。为了计算成本,它必须了解更大的结构。例如,较大的结构可能有48英寸宽。MyObject可以是8、12、24或48个乱伦。8英寸的比48英寸的成本更高,因为它需要使用6英寸。通过让MyObject知道其父对象,或者让父对象根据子对象计算成本,这样做更好吗?
    public static IEnumerable Extract(DbDataReader dr){int-omodelnumer=dr.GetOrdinal(“modelnumer”)、oIsStandardProduct=dr.GetOrdinal(“IsStandardProduct”)、oManufacturerName=dr.GetOrdinal(“ManufacturerName”),…而(dr.Read()){yield return new MyObject(){ModelNumber=dr.GetString(oModelNumber),IsStandardProduct=dr.GetBoolean(oIsStandardProduct),ManufacturerName=dr.GetString(oManufacturerName),…};}
    @OpusKrokus请更新问题。注释中的代码很难阅读,甚至更难理解。此外,我认为如果您发布
    GetRelativeCost
    函数也不会有什么坏处