Dervin Thunk
Dervin Thunk

Reputation: 20119

looping over char[] or substring(): Efficiency in C#?

does any of you know what would be better:

a. get a string s, convert to char array and loop over it, or

b. get a string s, loop over substrings of it (s.Substring(i, 1))?

Any tips much appreciated.

Upvotes: 2

Views: 7924

Answers (8)

Henk Holterman
Henk Holterman

Reputation: 273219

Option b), looping over substrings, is very inefficient.

The fastest method would be

c) loop over the string chars directly, using the read-only indexer property:

for (int i = 0; i < s.Length; i++) { char c = s[i]; ... }

or, based on the IEnumerable<char> interface:

foreach(char c in s) { ... }

Upvotes: 12

Raghav
Raghav

Reputation: 9630

While using substring remember that it will gives you the new string the orignal string will remain as it is.Wgy i am saying that orignal string will remain as it is because .NET interns its strings, so future instances will pull the same immutable string from the intern pool, and any performance hit will be negligible. In computer science, string interning is a method of storing only one copy of each distinct string value, which must be immutable. Interning strings makes some string processing tasks more time- or space-efficient at the cost of requiring more time when the string is created or interned. The distinct values are stored in a string intern pool. The single copy of each string is called its 'intern' and is typically looked up by a method of the string class. So by using substring every time you are creating new string So instead of substring choose the for loop option.

string str = "TestString";
for (int i = 0; i < str.Length; i++)
{
    char c = str[i];
}

Upvotes: 0

Matt Howells
Matt Howells

Reputation: 41266

(A) is much more efficient. But why not just do:

foreach (char c in s)

Some quick benchmarks indicate that this is a tiny bit (<2% difference) less efficient than

for(int i = 0; i < s.Length; ++i)
    char c = s[i];

But my opinion is that the readability of the former makes it superior for anything but the most time-critical code.

Upvotes: 6

Sam Harwell
Sam Harwell

Reputation: 99869

What exactly are you doing? When there is an optimized method for the string operation you are performing, it will tremendously outperform any kind of loop you come up with. As a simple example:

File.ReadAllLines(...);
...
Regex exp = new Regex(..., RegexOptions.Compiled);
foreach (line)
    exp.Match(...);

is much slower than:

File.ReadAllText(...);
...
foreach (match in Regex.Match(..., RegexOptions.Multiline))
    ...

Upvotes: 0

flq
flq

Reputation: 22849

b Sounds odd. Just guessing, but a sounds quicker, and certainly more understandable.

EDIT: Hence, if you want the index, yer old

for (int i = 0; i < s.Length; i++)
  //Do something with s[i]

will do fine

Or, for some LINQ overkill

s.Select((i, c) => //i being index, c the char, or the other way round, I forget at times);

Upvotes: 1

Michael Burr
Michael Burr

Reputation: 340198

Why convert the string to a char array? There's an indexer on the String class that lets you get the individual characters:

char c = s[i];

Upvotes: 1

Winston Smith
Winston Smith

Reputation: 21882

It depends what you are trying to do.

Do you just need to examine characters at particular indexes, or create a new string based on them or what?

Remember SubString() will return a new string. This may cause unwanted overhead depending on what you are trying to do. A clearer explanation of the problem would help.

Also, don't pre-optimize. Write your code whichever way you feel more productive. Then profile it and address this issue if it causes a bottleneck.

Upvotes: 3

Hardryv
Hardryv

Reputation: 793

it would be quicker to profile both routines with some large strings than research and / or wait for answers, but if I had to guess I'd wager A

Upvotes: 2

Related Questions