For an experiment, I tried this :
(1) Create 100000 classes, each of them wrapping a double variable
---This is the experiment part---
(2) Measured performance of two methods by running 100000 times :
create a double[] and assign the value of wrapped variables.
create a class[] and assign the reference of wrapping class.
The above may confuse you, so I am attaching the code :
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();
}
}
The result is as follows :
test.CopyValue() : 56890 (millisec)
test.CopyReference() : 66688 (millisec)
(built with release configuration and ran exe)
I tried several times, but the result doesn't change much. So I concluded that CopyReference() takes longer time.
But I hardly understand why. Here is the question :
I thought that, regardless of CopyValue() or CopyReference(), what my machine does is "Copying a number in memory" though one is double value and the another is reference to a class. So there should not be meaningful difference in performance, but the fact is not.
Then what is the difference between copying a value and copying a reference? Does copying a reference do more thing than copying a value?
(When passing a reference without ref keyword, isn't it true that reference is copied as if it were value? What I am saying is that,
ClassA x = new ClassA();
ClassA y = x;
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?)
If I am working with wrong assumptions, please let me know what I am wrong with.
I appreciate your help and advice.
-
I guessed that GC might have some impact, but turning off GC by TryStartNoGCRegion(Int64) doesn't change the conclusion. (both become faster, but still CopyReference() is slower.)