SO I tried to make an unsafe
fast method to count lines.
I previously used StringReader
, but wanted to see if I could make something faster.
So is this code valid, it seems to work but it looks a bit confusing,
and I am very new to C# pointers so I might be doing something bad.
Original Method:
//Return number of (non Empty) lines
private static int getLineCount(string input)
{
int lines = 0;
string line = null;
//Don't count Empty lines
using (StringReader reader = new StringReader(input))
while ((line = reader.ReadLine()) != null)
if (!string.IsNullOrWhiteSpace(line))
lines++;
return lines;
}
Unsafe Method:
//Return number of (non Empty) lines (fast method using pointers)
private unsafe static int getLineCountUnsafe(string input)
{
int lines = 0;
fixed (char* strptr = input)
{
char* charptr = strptr;
int length = input.Length;
//Don't count Empty lines
for (int i = 0; i < length; i++)
{
char c = *charptr;
//If char is an empty line, look if it's empty
if (c == '\n' || c == '\r')
{
//If char is empty, continue till it's not
while (c == '\n' || c == '\r')
{
if (i >= length)
return lines;
i++;
charptr++;
c = *charptr;
}
//Add a line when line is not just a new line (empty)
lines++;
}
charptr++;
}
return lines;
}
}
Benchmark:
(Looped through 100000, 10 times)
Total Milliseconds used.
Safe(Original) - AVG = 770.10334, MIN = 765.678, MAX = 778.0017 , TOTAL 07.701
Unsafe - AVG = 406.91843, MIN = 405.7931, MAX = 408.5505 , TOTAL 04.069
EDIT:
It seems that the Unsafe version isn't always correct, if it's one line it won't count it, been trying to solve it without making it count too many;(