gpt4 book ai didi

c# - 复制类的引用和复制值的区别

转载 作者:行者123 更新时间:2023-11-30 13:06:04 25 4
gpt4 key购买 nike

为了实验,我尝试了这个:

(1) 创建 100000 个类,每个类包装一个 double 变量

---这是实验部分---

(2) 两种方法运行100000次的实测性能:

  • 创建一个 double[] 并分配包装变量的值。

  • 创建一个类[]并分配包装类的引用。

上面的内容可能会让你感到困惑,所以我附上代码:

static void Main(string[] args)
{
int length = 100000;
Test test = new Test(length);

Stopwatch stopwatch = new Stopwatch();
stopwatch.Start();

for (int i = 0; i < length; i++)
test.CopyValue();
//test.CopyReference(); //test.CopyValue(); or test.CopyReference();

stopwatch.Stop();
Console.WriteLine("RunTime : {0} ", stopwatch.ElapsedMilliseconds);
}

class DoubleWrapper
{
public double value = 0.0;
}

class Test
{
DoubleWrapper[] wrapper;

public void CopyValue()
{
double[] x = new double[wrapper.Length];
for (int i = 0; i < wrapper.Length; i++)
x[i] = wrapper[i].value;
}

public void CopyReference()
{
DoubleWrapper[] x = new DoubleWrapper[wrapper.Length];
for (int i = 0; i < wrapper.Length; i++)
x[i] = wrapper[i];
}

public Test(int length)
{
wrapper = new DoubleWrapper[length];
for (int i = 0; i < length; i++)
wrapper[i] = new DoubleWrapper();
}
}

结果如下:

测试.CopyValue():56890(毫秒)

测试.CopyReference():66688(毫秒)

(使用发布配置构建并运行 exe)

我尝试了几次,但结果变化不大。所以我得出结论,CopyReference() 需要更长的时间。


但我几乎不明白为什么。这是问题:

我认为,无论 CopyValue() 还是 CopyReference(),我的机器所做的是“在内存中复制一个数字”,尽管一个是 double 值,另一个是对类的引用。所以在性能上应该没有有意义的差异,但事实并非如此。

那么复制一个值和复制一个引用有什么区别呢?复制引用是否比复制值更有效?

(当传递不带 ref 关键字的引用时,引用是否被复制为值?我的意思是,

ClassA x = new ClassA();
ClassA y = x;

意味着复制“x 的引用”,然后分配给变量 y,因此 y = null 根本不会影响 x。这是真的吗?)

如果我的假设是错误的,请告诉我我错在哪里。

非常感谢您的帮助和建议。

-

我猜GC可能会有一些影响,但是通过TryStartNoGCRegion(Int64)关闭GC并没有改变结论。(两者都变得更快,但 CopyReference() 仍然更慢。)

最佳答案

means making a copy of "reference of x" and then assigning to variable y, consequently y = null doesn't affect x at all. Is this true?

没错 - 您制作了一份引用资料的副本

现在,为什么您的 CopyReference 实现速度较慢?

您必须进行性能分析才能真正了解它,但最重要的是:

您正在该方法中创建 DoubleWrapper 引用类型 的新实例。请记住,C# 不是“零成本抽象”语言,而 C/C++/Rust 可能是。创建一个实例,即使是简单的引用类型,也只不过是对原始类型的简单包装,假设会花费更多。因为该实例中包含的不仅仅是一个简单的 double 值 - DoubleWrapper 对象的大小将不等于 8 个字节。

关于c# - 复制类的引用和复制值的区别,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52277008/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com