Eric Tsui
Eric Tsui

Reputation: 1924

Is there any possible performance issue for `foreach(var w in S.Split())` here?

Considering the code snippet

string S = "aa bb cc...";// very long string 
foreach(var w in S.Split()){// <-- how many invoke for Split() ?
                            // (Edited: After writing extension Method to test,
                            //it is invoked once.) 
    //do something
}

Is there any performance issue for the above code? Do I need to re write it as below?

string S = "aa bb cc...";
var strArray = S.Split();
foreach(var w in strArray){
    //do something
}

Upvotes: 0

Views: 99

Answers (2)

Christian Held
Christian Held

Reputation: 2828

Both code snippets generate the same code. Have look at the output of a decompiler (ILSpy in this case):

In DEBUG configuration (without code optimization);

string s = "aa bb cc...";
// foreach (string w in s.Split())
string[] array = s.Split();
foreach (string w in array)
{
    Console.WriteLine(w);
}

and

string s = "aa bb cc...";
// var stringArray = s.Split() ...
// foreach(var w in stringArray)
string[] stringArray = s.Split();
string[] array = stringArray;
foreach (string w in array)
{
    Console.WriteLine(w);
}

So you can see the second snippet will create one more reference to the string array, which should not make a big difference.

In RELEASE mode (with code optimization), the extra reference (array) will be removed, so both snippets generate the same code as foreach (string w in s.Split())

Upvotes: 2

Enigmativity
Enigmativity

Reputation: 117154

When I compile both versions of your code with optimizations turned on I get the same IL:

IL_0000:  ldstr       "aa bb cc..."
IL_0005:  call        System.Array.Empty
IL_000A:  callvirt    System.String.Split
IL_000F:  stloc.0     
IL_0010:  ldc.i4.0    
IL_0011:  stloc.1     
IL_0012:  br.s        IL_001C
IL_0014:  ldloc.0     
IL_0015:  ldloc.1     
IL_0016:  ldelem.ref  
IL_0017:  pop         
IL_0018:  ldloc.1     
IL_0019:  ldc.i4.1    
IL_001A:  add         
IL_001B:  stloc.1     
IL_001C:  ldloc.1     
IL_001D:  ldloc.0     
IL_001E:  ldlen       
IL_001F:  conv.i4     
IL_0020:  blt.s       IL_0014
IL_0022:  ret         

There is no difference between these two versions of the code (when optimized).

Upvotes: 4

Related Questions