views:

181

answers:

3

Say we have the following string

string data= "/temp string";

If we want to remove the first character / we can do by alot of ways such as :

data.Remove(0,1);
data.TrimStart('/');
data.Substring(1);

But .. really I don't know which one have the best algorithm and doing that faster ..
Is there a one that is the best or all are the same ?

+2  A: 

You could profile it, if you really cared. Write a loop of many iterations and see what happens. Chances are, however, that this is not the bottleneck in your application, and TrimStart seems the most semantically correct. Strive to write code readably before optimizing.

Stefan Kendall
`TrimStart` is the least correct, since `"//temp string".TrimStart('/')` will *not* just remove the first `'/'`.
Marcelo Cantos
The function is poorly named then. I'm not a C# guy.
Stefan Kendall
+3  A: 

I'd guess that Remove and Substring would tie for first place, since they both slurp up a fixed-size portion of the string, whereas TrimStart does a scan from the left with a test on each character and then has to perform exactly the same work as the other two methods. Seriously, though, this is splitting hairs.

Marcelo Cantos
Actually, `Substring` is faster than `Remove`, because `Remove` calls `Substring`.
Jaroslav Jandek
@Jaroslav: This is not true. Both `Substring` and `Remove` rely on a private method, `FillSubstring`.
Marcelo Cantos
Didn't verify it, but it very sounds plausible: `string Remove(this string source, int from, int to) { return source.SubString(0, from) + source.SubString(to); }`
Dykam
@Marcelo: maybe in `Singularity RDK`, but not in `.NET` (any version). `Substring` uses unsafe string copy (in memory).
Jaroslav Jandek
@Jaroslav: I'm staring at the Reflector disassembly of the two methods in mscorlib.dll on a fairly conventional Windows dev environment. They both call `System.PInvoke.EE.AllocateString` to allocate the destination string object and then call `FillSubstring` to copy characters across. Am I looking at the wrong thing?
Marcelo Cantos
@Marcelo: the point is: it does not really matter. True, the internal processes are very similar. There is only 1 allocation, **but** Remove has to do 2 copy functions while substring only has to do one (logically). Basically `Remove` does 2 substrings (do not nitpick on this please). What I mean is Remove does the opposite of substring. Eg.: For `"abcd"` `Substring` would return `"bc"` but `Remove` would return `"a" + "d"` (with one allocation) or `"bcd"`, respective `""+"bcd"` => it which will always be more expensive than a `Substring`. I hope you now understand.
Jaroslav Jandek
@Jaroslav: That wasn't your original point at all. If A calls B then it is (almost) a truism that A will be slower than B. Your latest claim, however, relies on several assumptions, such as the assumption that the overhead of `Remove`'s extra call to FillSubstring, which has no work to do, will outweigh the cost of `Substring`'s more complex parameter verification code. Don't get me wrong. I'm not disagreeing with your conclusion. Substring probably is faster (a matter one would settle by profiling, not speculating). Just don't pretend that we've been debating the same point from the outset.
Marcelo Cantos
@Marcelo: `Remove` *esentially* calls `substring` (work-wise) ((A + B) > A always - it does the same checks btw.). And yes, it is WAY slower than `Substring`. Like 80%+ slower for this specific operation. If you wanted to do a regular `Remove` from the middle of a string, even then is `Remove` only marginally (10%+) faster than `Substring`. Also, I see no calls to `FillSubstring` in my methods. The bottom line is the `SubString` is the best method for that as I have pointed out in the first comment on the original post.
Jaroslav Jandek
@Marcelo: Anyway, your first comment originally said a totaly different thing. I should probably have used a better wording, the point is valid though (`Substring` > `Remove`). I am not going to comment further because the discussion took enough of my time.
Jaroslav Jandek
+6  A: 

The second option really isn't the same as the others - if the string is "///foo" it will become "foo" instead of "//foo".

The first option needs a bit more work to understand than the third - I would view the Substring option as the most common and readable.

(Obviously each of them as an individual statement won't do anything useful - you'll need to assign the result to a variable, possibly data itself.)

I wouldn't take performance into consideration here unless it was actually becoming a problem for you - in which case the only way you'd know would be to have test cases, and then it's easy to just run those test cases for each option and compare the results. I'd expect Substring to probably be the fastest here, simply because Substring always ends up creating a string from a single chunk of the original input, whereas Remove has to at least potentially glue together a start chunk and an end chunk.

Jon Skeet
I do check now by call each one about 90000000 and I go the following result :Remove : 06.63 - TrimStart : 04.71 - subString : 03.09so from result substring is the best
Space Cracker