哪一个在内存方面更好?我一直使用片段2 .. Snippet 1是否比片段2(性能,内存)更好?
Snippet 1
public void GetListOfString(ref List<string> x)
{
x = new List<string>(){"Dave","John"};
}
Snippet 2
public List<string> GetListOfString()
{
return new List<string>(){"Dave","John"};
}
答案 0 :(得分:4)
首先,您的第一个示例应该使用out
,而不是ref
:
public void GetListOfString(out List<string> x)
该方法不关心传入值是什么;它只是覆盖了那里的一切。使用out
确保a)调用者在传递变量之前不需要初始化变量,并且b)方法本身 需要在返回之前初始化变量(这将确保防止错误)。
如果有任何性能差异(我怀疑你可以测量一个),我希望第一个例子更慢,因为它必须传递对变量的引用。传递引用意味着必须存在一个内存位置,该方法可以修改变量的值。返回值是一种高度优化的方案,其值通常甚至存储在寄存器中。如果变量未通过引用传递,那么编译器也可以注册调用者的变量,以获得额外的性能增益。
当然,如果数据保存在寄存器中而不是存储在堆栈中,那么代表了(边缘的,无关紧要的,完全不重要的)内存占用减少。
但无论如何,性能和内存占用不应成为您首要关注的问题。主要关注点是,仅关注的所有代码的99.94%是在语义和操作上有意义的。如果该方法需要修改调用者的变量,则根据场景适当地按引用ref
或out
传递。如果没有,则传递by-value。周期。
请注意,如果只需要修改调用者的一个变量,并且该方法不必返回任何内容(即void
),那么让调用者认为这是一个更好的做法处理修改变量,只返回变量的新值(即在第二个例子中)。
如果您在代码中出现问题,由于某种原因,您无法实现某些特定的和可衡量的性能或内存占用目标,并且您可以证明使用传递引用将确保您实现该目标,然后您可以将性能作为传递引用的动机。否则,不要再考虑一下。
答案 1 :(得分:1)
Snippet 2在可读性和可用性方面要好得多。
在性能和内存方面可能稍微好一些。
但这只是因为调用者被迫创建一个新的列表来调用代码片段1.你可以说这个开销会被编译器优化掉,但不要依赖它。
如果您使用out
代替ref
代码片段1,那么我会说它们在性能和内存方面都是相同的。
我可以同情来自不同编程语言背景的人认为片段1会更好,但在C#中,引用类型是通过引用返回的,而不是像其他语言一样被复制。