计算行数,此不安全方法是否有效

本文关键字:方法 是否 有效 不安全 计算 | 更新日期: 2023-09-27 18:18:04

所以我尝试制作一个unsafe快速方法来计数行。我以前使用的是StringReader,但我想看看我是否能做得更快。

这段代码是有效的吗,它似乎可以工作,但它看起来有点混乱,

和我对c#指针非常陌生,所以我可能做了一些不好的事情。

原始方法:

//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;
}
不安全方法:

//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;
    }
}
基准:

(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
编辑:

似乎不安全的版本并不总是正确的,(

计算行数,此不安全方法是否有效

)如果它是一行,它不会计算它,我一直在努力解决它,而不是让它计算太多;

你的第二个实现似乎还可以,但不要太费心学习unsafe,它在c#中没有那么广泛使用,也不是指针。这越来越接近c++了。这两种方法之间的时间差可能来自于避免垃圾收集器收集方法内部的任何内存,直到完成为止(因为fixed关键字)。

很少使用unsafe的原因是因为c#在它已经定义的方法中提供了很多可读性和易用性,就像你的例子:
//Return number of (non Empty) lines
private static int getLineCount(string input)
{
     return Regex.Matches(input, Environment.NewLine).Count;
}

,其中可能更快,因为一次性求值整个字符串。