True Unsafe Code Performance

I understand unsafe code is more appropriate to access things like the Windows API and do unsafe type castings than to write more performant code, but I would like to ask you if you have ever noticed any significant performance improvement in real-world applications by using it when compared to safe c# code.


Solution 1:

Some Performance Measurements

The performance benefits are not as great as you might think.

I did some performance measurements of normal managed array access versus unsafe pointers in C#.


Results from a build run outside of Visual Studio 2010, .NET 4, using an Any CPU | Release build on the following PC specification: x64-based PC, 1 quad-core processor. Intel64 Family 6 Model 23 Stepping 10 GenuineIntel ~2833 Mhz.

Linear array access
 00:00:07.1053664 for Normal
 00:00:07.1197401 for Unsafe *(p + i)

Linear array access - with pointer increment
 00:00:07.1174493 for Normal
 00:00:10.0015947 for Unsafe (*p++)

Random array access
 00:00:42.5559436 for Normal
 00:00:40.5632554 for Unsafe

Random array access using Parallel.For(), with 4 processors
 00:00:10.6896303 for Normal
 00:00:10.1858376 for Unsafe

Note that the unsafe *(p++) idiom actually ran slower. My guess this broke a compiler optimization that was combining the loop variable and the (compiler generated) pointer access in the safe version.

Source code available on github.

Solution 2:

As was stated in other posts, you can use unsafe code in very specialised contexts to get a significant performance inprovement. One of those scenarios is iterating over arrays of value types. Using unsafe pointer arithmetic is much faster than using the usual pattern of for-loop/indexer..

struct Foo
{
    int a = 1;
    int b = 2;
    int c = 0;
}

Foo[] fooArray = new Foo[100000];

fixed (Foo* foo = fooArray)  // foo now points to the first element in the array...
{
    var remaining = fooArray.length;
    while (remaining-- > 0)
    {
        foo->c = foo->a + foo->b;
        foo++;  // foo now points to the next element in the array...
    }
}

The main benefit here is that we've cut out array index checking entirely..

While very performant, this kind of code is hard to handle, can be quite dangerous (unsafe), and breaks some fundamental guidelines (mutable struct). But there are certainly scenarios where this is appropriate...

Solution 3:

A good example is image manipulations. Modifying the Pixels by using a pointer to their bytes (which requires unsafe code) is quite a bit faster.

Example: http://www.gutgames.com/post/Using-Unsafe-Code-for-Faster-Image-Manipulation.aspx

That being said, for most scenarios, the difference wouldn't be as noticeable. So before you use unsafe code, profile your application to see where the performance bottlenecks are and test whether unsafe code is really the solution to make it faster.

Solution 4:

Well, I would suggest to read this blog-post: MSDN blogs: Array Bounds Check Elimination in the CLR

This clarifies how bounds-checks are done in C#. Moreover, Thomas Bratts tests seem to me useless (looking at the code) since the JIT removes in his 'save' loops the bound-checks anyway.