繁体   English   中英

C# .NET 中按值传递与按引用传递的性能

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM