7

I recently changed

        this.FieldValues = new object[2, fieldValues.GetUpperBound(1) + 1];
        for (int i = 0; i < FieldCount; i++)            
        {
            this.FieldValues[Current, i] = fieldValues[Current, i];
            this.FieldValues[Original, i] = fieldValues[Original, i];
        }

to

        FieldValues = new object[2, fieldValues.GetLength(1)];
        Array.Copy(fieldValues, FieldValues, FieldValues.Length); 

Where the values of Current and Original are constants 0 and 1 respectively. FieldValues is a field and fieldValues is a parameter.

In the place I was using it, I found the Array.Copy() version to be faster. But another developer says he timed the for-loop against Array.Copy() in a standalone program and found the for-loop faster.

Is it possible that Array.Copy() is not really faster? I thought it was supposed to be super-optimised!

5
  • 17
    It's very important, if you care about performance details such as this, that you be able to write simple benchmarking programs :) Commented Sep 20, 2011 at 10:47
  • 3
    And have the knowledge what is going under the hood. Commented Sep 20, 2011 at 10:51
  • 1
    My assumption is that Array.Copy would be faster than looping especially as the size of the array grows. Besides when you have the option of using a framework method vs hand rolling your own ... you should always use the framework method unless you have a very specific and measurable requirement to do otherwise. Commented Sep 20, 2011 at 10:57
  • 2
    Most likely: it is totally irrelevant. Commented Sep 20, 2011 at 11:25
  • 1
    It's NOT irrelevant. I have run a profiler over the code, in a situation that was causing performance problems and identified this as the biggest hot-spot. In that situation, using Array.Copy() made it noticably faster, but in the standalone test program, Array.Copy() seemed to lose out to the for-loop. Commented Sep 20, 2011 at 12:56

3 Answers 3

12

In my own experience, I've found that I can't trust my intuition about anything when it comes to performance. Consequently, I keep a quick-and-dirty benchmarking app around (that I call "StupidPerformanceTricks"), which I use to test these scenarios. This is invaluable, as I've made all sorts of surprising and counter-intuitive discoveries about performance tricks. It's also important to remember to run your benchmark app in release mode, without a debugger attached, as you otherwise don't get JIT optimizations, and those optimizations can make a significant difference: technique A might be slower than technique B in debug mode, but significantly faster in release mode, with optimized code.

That said, in general, my own testing experience indicates that if your array is < ~32 elements, you'll get better performance by rolling your own copy loop - presumably because you don't have the method call overhead, which can be significant. However, if the loop is larger than ~32 elements, you'll get better performance by using Array.Copy(). (If you're copying ints or floats or similar sorts of things, you might also want to investigate Buffer.BlockCopy(), which is ~10% faster than Array.Copy() for small arrays.)

But all that said, the real answer is, "Write your own tests that match these precise alternatives as closely as possible, wrap them each with a loop, give the loop enough iterations for it to chew up at least 2-3 seconds worth of CPU, and then compare the alternatives yourself."

Sign up to request clarification or add additional context in comments.

Comments

5

The way .Net works under the hood, I'd guess that in an optimized situation, Array.Copy would avoid bounds checking.

If you do a loop on any type of collection, by default the CLR will check to make sure you're not passing the end of the collection, and then the JIT will either have to do a runtime assessment or emit code that doesn't need checking. (check the article in my comment for better details of this)

You can modify this behaviour, but generally you don't save that much. Unless you're in a tightly executed inner loop where every millisecond counts, that is.

If the Array is large, I'd use Array.Copy, if it's small, either should perform the same.

I do think it's bounds checking that's creating the different results for you though.

1 Comment

It's a lengthy read but this is a great MSDN blog about bounds checking optimisation: blogs.msdn.com/b/clrcodegeneration/archive/2009/08/13/…
-6

In your particular example, there is a factor that might (in theory) indicate the for loop is faster.

Array.Copy is a O(n) operation while your for loop is O(n/2), where n is the total size of you matrix.

Array.Copy needs to loop trough all the elements in your two-dimensional array because:

When copying between multidimensional arrays, the array behaves like a long one-dimensional array, where the rows (or columns) are conceptually laid end to end. For example, if an array has three rows (or columns) with four elements each, copying six elements from the beginning of the array would copy all four elements of the first row (or column) and the first two elements of the second row (or column).

1 Comment

This answer shows a total misunderstanding of what O(n) notation means.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.