What is the fastest way to count newlines in a large .NET string?

前端 未结 6 1816
闹比i
闹比i 2021-02-13 04:18

Is there a way to improve this:

private static int CountNewlines(string s)
{
    int len = s.Length;
    int c = 0;
    for (int i=0; i < len;  i++)
    {
           


        
6条回答
  •  余生分开走
    2021-02-13 05:04

    I tested these implementations

    private static int Count1(string s)
    {
        int len = s.Length;
        int c = 0;
        for (int i=0; i < len;  i++)
        {
            if (s[i] == '\n') c++;
        }
        return c+1;
    }
    
    private static int Count2(string s)
    {
        int count = -1;
        int index = -1;
    
        do
        {
            count++;
            index = s.IndexOf('\n', index + 1);
        }
        while (index != -1);
    
        return count+1;
    }
    
    private static int Count3(string s)
    {
        return s.Count( c => c == '\n' ) + 1;
    }
    
    
    private static int Count4(string s)
    {
        int n = 0;
        foreach( var c in s )
        {
            if ( c == '\n' ) n++;
        }
        return n+1;
    }
    
    private static int Count5(string s)
    {
        var a = s.ToCharArray();
        int c = 0;
        for (int i=0; i < a.Length; i++)
        {
            if (a[i]=='\n') c++;
        }
        return c+1;
    }
    

    Here are my timing results for 100000 iterations on a string of ~25k. Lower is faster.

                  Time  Factor
    Count1   4.8581503     1.4
    Count2   4.1406059     1.2
    Count3  45.3614124    13.4
    Count4   3.3896130     1.0
    Count5   5.9304543     1.7
    

    Surprisingly, to me, the Enumerator implementation was fastest for me, by a significant degree - 20% faster than the next closest implementation. The results were repeatable, regardless of the order in which the methods were run. I also used a warmup phase to insure transient effects (jit, etc) were factored out.

    This was for a release build (/optimize+)

提交回复
热议问题