Share via


C# performance: comparing string.Empty with double quote (empty string)

In the spirit of performance, there is a funny point about string comparaison.

In the left corner, string.empty comparison.

  1. string myValue = "I love C#";  
  2. if (myValue != String.Empty)  
  3.     Console.Out.WriteLine("I'm loving it!");  

and in the right corner double quote comparison:

  1. string myValue = "I love C#";  
  2. if (myValue != "")  
  3.      Console.Out.WriteLine("I'm loving it!");  

 

With a loop with 500000 iterations, execution time for string.empty comparaison is more than 5% than double quote comparaison.

Why ?

Have a look in the IL Code:

string.empty comparison:

  1. .method private hidebysig static void  Main() cil managed  
  2. {  
  3.   .entrypoint  
  4.   // Code size       42 (0x2a)  
  5.   .maxstack  2  
  6.   .locals init ([0] string myValue,  
  7.            [1] bool CS$4$0000)  
  8.   IL_0000:  nop  
  9.   IL_0001:  ldstr      "I love C#"  
  10.   IL_0006:  stloc.0  
  11.   IL_0007:  ldloc.0  
  12.   IL_0008:  ldsfld     string [mscorlib]System.String::Empty  
  13.   IL_000d:  call       bool [mscorlib]System.String::op_Inequality(string,  
  14.                                                                    string)  
  15.   IL_0012:  ldc.i4.0  
  16.   IL_0013:  ceq  
  17.   IL_0015:  stloc.1  
  18.   IL_0016:  ldloc.1  
  19.   IL_0017:  brtrue.s   IL_0029  
  20.   IL_0019:  call       class [mscorlib]System.IO.TextWriter [mscorlib]System.Console::get_Out()  
  21.   IL_001e:  ldstr      "I'm loving it!"  
  22.   IL_0023:  callvirt   instance void [mscorlib]System.IO.TextWriter::WriteLine(string)  
  23.   IL_0028:  nop  
  24.   IL_0029:  ret  
  25. } // end of method Pro  
  26. gram::Main  

 

double quote comparison:

  1. .method private hidebysig static void  Main() cil managed  
  2. {  
  3.   .entrypoint  
  4.   // Code size       42 (0x2a)  
  5.   .maxstack  2  
  6.   .locals init ([0] string myValue,  
  7.            [1] bool CS$4$0000)  
  8.   IL_0000:  nop  
  9.   IL_0001:  ldstr      "I love C#"  
  10.   IL_0006:  stloc.0  
  11.   IL_0007:  ldloc.0  
  12.   IL_0008:  ldstr      ""  
  13.   IL_000d:  call       bool [mscorlib]System.String::op_Inequality(string,  
  14.                                                                    string)  
  15.   IL_0012:  ldc.i4.0  
  16.   IL_0013:  ceq  
  17.   IL_0015:  stloc.1  
  18.   IL_0016:  ldloc.1  
  19.   IL_0017:  brtrue.s   IL_0029  
  20.   IL_0019:  call       class [mscorlib]System.IO.TextWriter [mscorlib]System.Console::get_Out()  
  21.   IL_001e:  ldstr      "I'm loving it!"  
  22.   IL_0023:  callvirt   instance void [mscorlib]System.IO.TextWriter::WriteLine(string)  
  23.   IL_0028:  nop  
  24.   IL_0029:  ret  
  25. } // end of method Progra  
  26. m::Main  

 

Only one line difference.

In double quote comparaison, the "" value is loaded from the stack.

In string.empty comparaison, the string.Empty object reference is loaded from metadata.

 

Loading from metadata is longer than loading from the stack.

If you are on a real time server and you want absolute performance, 5% is important. In another cases, string.empty comparaison is safe and your code will be more readable.