为进行实验,我尝试了此操作:
(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();
}
}
结果如下:
test.CopyValue():56890(millisec)
test.CopyReference():66688(millisec)
(使用发行版配置构建并运行exe)
我尝试了几次,但结果并没有太大变化。 因此,我得出结论,CopyReference()需要更长的时间。
但是我几乎不明白为什么。这是问题:
我认为,不管CopyValue()或CopyReference(),我的机器执行的操作都是“在内存中复制数字”,尽管一个是双精度值,而另一个是对类的引用。因此,性能上不应有有意义的差异,但事实并非如此。
那么复制值和复制引用之间有什么区别? 复制引用比复制值做更多的事情吗?
(当传递不带ref关键字的引用时,是不是真的像复制了引用一样复制了引用呢?
ClassA x = new ClassA();
ClassA y = x;
意味着复制“ x的引用”,然后分配给变量y,因此y = null根本不会影响x。这是真的吗?)
如果我使用错误的假设,请让我知道我的错。
感谢您的帮助和建议。
-
我猜测GC可能会产生一些影响,但是通过TryStartNoGCRegion(Int64)关闭GC不会改变结论。 (两者都变快,但CopyReference()仍然变慢。)
答案 0 :(得分:0)
表示复制“ x的引用”,然后赋给变量 y,因此y = null根本不影响x。这是真的吗?
是的-您制作了副本参考。
现在,为什么您执行CopyReference
的速度变慢呢?
您必须进行性能分析才能获得有关它的真正见解,但最重要的是:
您正在该方法内创建DoubleWrapper
引用类型的新实例。
请记住,C#
不是像C/C++/Rust
那样的“零成本抽象”语言。
创建一个甚至简单的引用类型的实例,它只不过是对原始类型的简单包装而已,因此可能会花费更多。因为该实例中包含的内容比简单的double
值要多-DoubleWrapper
对象的大小将不等于8个字节。
答案 1 :(得分:-1)
阅读有关堆栈和堆的信息可能有助于您理解。如果复制引用,则实际上是将显示的指针复制到堆中的实际对象,并且如果该实际对象发生更改,则这些更改将显示在引用该对象的所有事物上。
如果执行“深层复制”或克隆(如实现IClonable时的克隆),则将在堆栈中复制该数据并创建一个指向它的指针,因此不再依赖原始对象。
我希望这个解释对您有所帮助?参见https://www.c-sharpcorner.com/article/C-Sharp-heaping-vs-stacking-in-net-part-i/,了解有关堆栈和堆的信息。