0

I tried to find out which is the fastest method for copying a string array by using this code:

static void Main(string[] args)
    {
        Stopwatch copy = new Stopwatch();
        Stopwatch copyTo = new Stopwatch();
        Stopwatch direct = new Stopwatch();
        Stopwatch clone = new Stopwatch();

        string[] animals = new string[1000];
        animals[0] = "dog";
        animals[1] = "cat";
        animals[2] = "mouse";
        animals[3] = "sheep";
        for (int i = 4; i < 1000; i++)
        {
            animals[i] = "animal";
        }

        copy.Start();
        string[] copyAnimals = new string[animals.Length];
        Array.Copy(animals, copyAnimals, animals.Length);
        copy.Stop();
        Console.WriteLine("Copy: " + copy.Elapsed);

        copyTo.Start();
        string[] copyToAnimals = new string[animals.Length];
        animals.CopyTo(copyToAnimals, 0);
        copyTo.Stop();
        Console.WriteLine("Copy to: " + copyTo.Elapsed);

        direct.Start();
        string[] directAnimals = new string[animals.Length];
        directAnimals = animals;
        direct.Stop();
        Console.WriteLine("Directly: " + direct.Elapsed);

        clone.Start();
        string[] cloneAnimals = (string[])animals.Clone();
        clone.Stop();
        Console.WriteLine("Clone: " + clone.Elapsed);

    }

In most cases the ranking by fastest is: CopyTo(), Clone(), Directly, Copy(), however it is not absolutely consistent. What is your experience? Which one do you use the most and why?

Alexander Popov
  • 23,073
  • 19
  • 91
  • 130
  • you're doing different things and this is not a question. – Rafa Jul 03 '13 at 11:28
  • http://stackoverflow.com/questions/5099604/c-any-faster-way-of-copying-arrays – jAC Jul 03 '13 at 11:29
  • Would you please clarify? – Alexander Popov Jul 03 '13 at 11:29
  • Direct assign is not a copy indeed. All other methods are similiar. Also you missed old good for/froeach loop. Finally, if you run this program one time or too, it's a mistake in measurement. – Tommi Jul 03 '13 at 11:29
  • Read the FAQ, escpecially this part: http://stackoverflow.com/help/dont-ask – jAC Jul 03 '13 at 11:30
  • What is the direct assing? Why is this not copying? – Alexander Popov Jul 03 '13 at 11:31
  • 2
    `string[] directAnimals = new string[animals.Length]; directAnimals = animals;` You just create another reference to animals array. Now you can modify animals and will see that directAnimals also modified. This is not a copy. – Tommi Jul 03 '13 at 11:32
  • 2
    asigning ist this `array1 = array2` but this is not copying. It's referencing. – jAC Jul 03 '13 at 11:32
  • But after all, all other methods perform shallow copying, so that array2 will reference the objects of array1. Isn't this the same? – Alexander Popov Jul 03 '13 at 11:34
  • 1
    No, not the same. In other methods, if you assign array[0] = null, it will not affect array2[0], in direct assignment it will. – Tommi Jul 03 '13 at 11:36
  • 1
    The code that you are testing is doing way too little work to measure the performance time reliably, which also your results show. Direct assignment should always be about 1000 times faster than copying the array. – Guffa Jul 03 '13 at 11:40

1 Answers1

1

Array.CopyTo is just a wrapper around Array.Copy. That is, CopyTo does essentially this:

void CopyTo(Array dest, int length)
{
    Array.Copy(this, dest, length);
}

So Copy will be slightly faster than CopyTo (one less indirection).

Your direct copy doesn't actually copy the array. It just copies the reference. That is, given this code:

    string[] directAnimals = new string[animals.Length];
    directAnimals = animals;

If you then write animals[0] = "Penguin";, then directAnimals[0] will also contain the value "Penguin".

I suspect that Clone will be the same as Array.Copy. All it does it allocate a new array and copy the values to it.

Some notes on timing:

Your tests are doing far too little work to time accurately. If you want meaningful results, you'll have to execute each test many times. Something like:

copyTo.Start();
for (int i = 0; i < 1000; ++i)
{
    string[] copyToAnimals = new string[animals.Length];
    animals.CopyTo(copyToAnimals, 0);
}
copyTo.Stop();
Console.WriteLine("Copy to: " + copyTo.Elapsed);

For such small arrays, 1,000 times might not even be enough. You might need a million just to see if there's any meaningful difference.

Also, your results will be meaningless if you run these tests in the debugger. Be sure to compile in release mode and run with the debugger detached. Either execute from the command line, or use Ctrl+F5 in Visual Studio.

Jim Mischel
  • 131,090
  • 20
  • 188
  • 351
  • Thank you! One question though: you say "So CopyTo will be slightly faster (one less indirection)." Shouldn't Copy() be faster than CopyTo(), as the latter redirects to the former, so that we have "one less indirection" in the case of Copy(), not CopyTo()? – Alexander Popov Jul 04 '13 at 06:02
  • @AlexBG: You were right. I corrected my post. – Jim Mischel Jul 04 '13 at 09:42