문제

There is a guy on the project I'm helping with that puts unsafe tag everywhere in the performance important code, whether it is needed, or not. Usually this tag can be removed safely, but unfortunately it's very hard to prove him, that he should not do that. Can anybody give me a good authority article, that proves my or his point, so we could finally close the question?

An example of the code where he used unsafe:

            unsafe
            {
                writeableBmp.CopyPixels(new Int32Rect(1, 0, (int)(width - 1), (int)height - 1), buffer, writeableBmp.BackBufferStride, 0);
                writeableBmp.Lock();
                writeableBmp.WritePixels(new Int32Rect(0, 0, (int)width - 1, (int)height - 1), buffer, writeableBmp.BackBufferStride, 0, 0);
                writeableBmp.AddDirtyRect(new Int32Rect(0, 0, (int)width - 1, (int)height - 1));
                writeableBmp.Unlock();
            }

His point is that he read somewhere that unsafe is needed, and improves performance by giving a hint to compiler, that the code piece should be compiled differently.

도움이 되었습니까?

해결책

Well according to http://msdn.microsoft.com/en-us/library/t2yzs44b.aspx unsafe only creates an unsafe context. This is only required when using pointer arithmetic, etc. which is regarded as unsafe and therefore need an unsafe context being created.

In any other case it does not benefit at all as it does not disable anything.

Profile a code with and without it or check the MSIL to prove it.

Just remove it, if there is unsafe code, the compiler will tell you.

Some approach to it:

using System.Threading.Tasks;
using System.Xml;
using System.Xml.Linq;
using System.Xml.Serialization;

namespace CSharpTestbench
{
    class Program
    {
        static void Main(string[] args)
        {

            int x = 42;
            if (x == 42)
            {
                Console.WriteLine("it is 42");
            }
        }
    }
}

Looks in the non optimized MSIL code that way:

.method private hidebysig static void  Main(string[] args) cil managed
{
  .entrypoint
  // Code size       30 (0x1e)
  .maxstack  2
  .locals init ([0] int32 x,
           [1] bool CS$4$0000)
  IL_0000:  nop
  IL_0001:  ldc.i4.s   42
  IL_0003:  stloc.0
  IL_0004:  ldloc.0
  IL_0005:  ldc.i4.s   42
  IL_0007:  ceq
  IL_0009:  ldc.i4.0
  IL_000a:  ceq
  IL_000c:  stloc.1
  IL_000d:  ldloc.1
  IL_000e:  brtrue.s   IL_001d
  IL_0010:  nop
  IL_0011:  ldstr      "it is 42"
  IL_0016:  call       void [mscorlib]System.Console::WriteLine(string)
  IL_001b:  nop
  IL_001c:  nop
  IL_001d:  ret
} // end of method Program::Main

Decorating it with unsafe result in:

.method private hidebysig static void  Main(string[] args) cil managed
{
  .entrypoint
  // Code size       32 (0x20)
  .maxstack  2
  .locals init ([0] int32 x,
           [1] bool CS$4$0000)
  IL_0000:  nop
  IL_0001:  nop
  IL_0002:  ldc.i4.s   42
  IL_0004:  stloc.0
  IL_0005:  ldloc.0
  IL_0006:  ldc.i4.s   42
  IL_0008:  ceq
  IL_000a:  ldc.i4.0
  IL_000b:  ceq
  IL_000d:  stloc.1
  IL_000e:  ldloc.1
  IL_000f:  brtrue.s   IL_001e
  IL_0011:  nop
  IL_0012:  ldstr      "it is 42"
  IL_0017:  call       void [mscorlib]System.Console::WriteLine(string)
  IL_001c:  nop
  IL_001d:  nop
  IL_001e:  nop
  IL_001f:  ret
} // end of method Program::Main

Both are compiled with /unsafe of course. Actually the unsafe code has more instructions which yield in a slightly larger executable but should be neglectable. The unsafe calls are just replaced by a NOP CIL instruction that literally "does nothing" expect increasing the size of the executable (http://en.wikipedia.org/wiki/List_of_CIL_instructions).

It increases the indention and makes the code harder to read as it also implies that there is unsafe code.

R# also says that is unnecessary.

What proof does the developer has, that supports this claim?

다른 팁

Here's your link: http://en.wikipedia.org/wiki/Premature_optimization#When_to_optimize

Apart from the reason that he is completely and utterly wrong in assuming unsafe makes the code faster, using random keywords to maybe affect the performance is not how any professional develops code.

First, write the code, with a good balance of performance to code complexity - i.e. if you can write cleaner coder that runs faster, do it. If you can write messier code that runs even faster, don't. Second, figure out if the performance is sufficient. If it is, you're done. If it's not, figure out which part is affecting your performance the most, fix that one, and leave the other parts alone.

Back to unsafe: Unsafe is not faster. It allows you to write faster less safe (a.k.a. unsafe) code if you know how to do so, by allowing you to compile code that otherwise won't be compiled. But putting unsafe around normal code is not going to make any positive performance difference.

Unfortunately for you, your coworker is so far off that it will be difficult to find an article dedicated to the question "is unsafe code faster by default". Because it is neither stated nor implied anywhere that unsafe code is faster by default, the burden of proof should be on him. But without any capable seniors or managers around it may be difficult to convince him that that's the case. So the best point of attack I can see is the premature optimization one - if his more complex code is faster he must prove it.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top