【问题标题】:Parameter passing to method to remove object creation将参数传递给方法以删除对象创建
【发布时间】:2014-07-16 10:31:56
【问题描述】:

我刚搬到的一个项目中有以下代码,它在我们的团队中引发了一场争论,这是否是正确的方法:

public void Method()
{
    var reusableList = new List<string>();
    for (int i = 0; i < 100000000; i++)
    {
        var result = HelperMethod(i, reusableList);
    }
}

private static object HelperMethod(int someObject, List<string> something)
{
    something.Clear();
    //do something with the list
    something.Add(someObject.ToString());
    return something[0];
}

方法“Method”多次使用helper方法循环处理一些数据(这里的代码当然不是真正的代码......)并将可重用列表传递给helper方法以减少内存目的和性能目的。 在方法“方法”中没有使用该列表(这会降低代码的可读性),但是一遍又一遍地创建它会降低性能并增加内存消耗,这里最好的方法是什么?

【问题讨论】:

  • 在提出问题时,请注意格式化代码 - 只需多花几秒钟的时间,可读性就会大不相同。
  • “一遍又一遍地创建它会降低性能并增加内存消耗” - 您是否证实是这种情况?请注意,您最终会得到更少的对象,但它们会更持久。垃圾收集器非常擅长处理短寿命的对象。
  • 你测试过代码吗?您担心什么性能受到影响。我的建议是不要尝试优化代码段,除非您确定它会导致问题。这种创建和删除List&lt;string&gt; 的操作不太可能成为您代码的瓶颈...
  • 这里失去可读性的成本远远超过实现的性能提升 - 这可能非常小,因为创建 List 实际上并不是那么繁重的操作。
  • 我想我必须添加一些东西——当我第一次在代码中看到这种模式时,我很震惊,因为它违背了我所知道的一切,但是在进行内存测试时,我们发现它减少了内存,因为它是 1持久列表与创建几百万个列表,这些列表稍后会被垃圾收集。此代码是较大代码的一部分,该代码需要非常快且内存占用少。很难衡量这种优化对系统的整体影响,而且孤立的测试并不能很好地显示整个应用程序会发生什么。

标签: c# performance memory


【解决方案1】:

List&lt;T&gt; 在内部使用数组。如果您将新项目添加到列表中并且数组中没有剩余空间,则会分配一个双倍大小的新数组,并且当前数组中的所有对象都将被复制到新数组中。这需要一些时间。根据数组中的项目数量,这可能会产生影响。尤其是在向其中添加大量项目时。像您一样使用列表的“共享”实例时,List&lt;T&gt; 的内部数组在您调用 List&lt;T&gt;.Clear() 时不会缩小。使用此实例一段时间后,您不再有此开销。作为替代方案,当您期望列表中有很多项目时,您可以在构造函数中指定列表的初始容量。

这意味着:理论上它更快。但我怀疑你是否真的认识到差异。

我希望代码可读性好

【讨论】:

  • 不确定你的意思:“cood reaFirst”我知道 clear 不会改变内部数组的大小,如果需要的列表大小大致相同,这只会使这个更多从性能的角度来看很有帮助,不是吗?
  • 对不起。修正了这句话。再次,这取决于情况。如果你真的需要性能,对象缓存/重用可能是一种可行的方法。
【解决方案2】:

首先Method() 不会被for 循环反复执行。如果您在谈论HelperMethod(),那么一遍又一遍地调用它不会有任何内存问题,因为一旦执行它,它创建的所有资源(int and List&lt;string&gt;)都将被释放。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-09-26
    相关资源
    最近更新 更多