[英]Performance of pass by value vs. pass by reference in C# .NET
我创建了一个带有构造函数的轻量级类,该类带有大约 10 个参数。 该类不会更改参数值; 它只是通过构造函数在本地存储值。
一些参数是引用类型(字符串、类),其他参数是值类型(int、bool、enums)。
我的问题是我应该通过引用传递所有参数(类除外),即使用关键字ref
吗?
我在这里考虑的是性能。
仅当方法需要更改参数时才使用ref
,并且这些更改需要传递到调用代码中。 如果您已经通过分析器运行它并确定瓶颈确实是 CLR 将方法参数复制到堆栈上,那么您应该只优化它。
请记住,CLR 为调用带参数的方法进行了大量优化,所以我不应该认为这是问题所在。
不。对于引用类型,您已经在传递引用,除非您想更改引用指向的内容,例如为其分配一个新对象,否则无需通过引用传递引用。 对于值类型,您可以通过引用传递,但除非您有性能问题,否则我不会这样做。 特别是如果所讨论的类型很小(4 个字节或更少),则性能提升很小或没有,甚至可能会受到惩罚。
我发现在对较大值类型的大量函数调用中,通过 ref 传递的速度稍快一些。 如果您有大量的函数调用并且需要速度,这可能是一个考虑因素。 我对其他证据持开放态度。
public static void PassValue(decimal value)
{
}
public static void PassRef(ref decimal value)
{
}
decimal passMe = 0.00010209230982047828903749827394729385792342352345m;
for (int x = 0; x < 20; x++)
{
DateTime start = DateTime.UtcNow;
TimeSpan taken = new TimeSpan();
for (int i = 0; i < 50000000; i++)
{
PassValue(passMe);
}
taken = (DateTime.UtcNow - start);
Console.WriteLine("Value : " + taken.TotalMilliseconds);
start = DateTime.UtcNow;
for (int i = 0; i < 50000000; i++)
{
PassRef(ref passMe);
}
taken = (DateTime.UtcNow - start);
Console.WriteLine("Ref : " + taken.TotalMilliseconds);
}
结果:
Value : 150
Ref : 140
Value : 150
Ref : 143
Value : 151
Ref : 143
Value : 152
Ref : 144
Value : 152
Ref : 143
Value : 154
Ref : 144
Value : 152
Ref : 143
Value : 154
Ref : 143
Value : 157
Ref : 143
Value : 153
Ref : 144
Value : 154
Ref : 147
Value : 153
Ref : 144
Value : 153
Ref : 144
Value : 153
Ref : 146
Value : 152
Ref : 144
Value : 153
Ref : 143
Value : 153
Ref : 143
Value : 153
Ref : 144
Value : 153
Ref : 144
Value : 152
Ref : 143
据我了解,您有一个只有字段的类和一个将参数分配给这些字段的构造函数,对吗?
如果是这种情况,我会考虑在构造函数中使用 ref 不好的做法。 如果您将参数分配给该类中的字段,则无论如何它都是按值存储的。 因此,如果您不更改构造函数中的值,则无需通过引用使用它。
不。通过引用传递参数会增加开销,因此只会降低性能。
我不确定 c#,但是对于 c++/c,它取决于您传递的内容。 如果您传递的是基本类型(int、float、double、char)...那么按值传递比按引用传递要快(因为函数调用已为此进行了优化。如果您传递的是更大的大类,一个数组,长字符串......然后通过引用传递要快得多,因为如果你在做一个 int[100000] 那么处理器将不得不分配一个 100000 x 32/64(取决于架构)块,然后复制所有的值都结束了,这需要很多时间。而通过引用只是传递一个指针
C#抽象了大部分,所以我不知道它是做什么的,但我认为在效率方面适用于c++/c的东西通常可以适用于c#。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.