计算线,这种不安全方法有效吗?

时间:2016-11-15 13:18:38

标签: c# unsafe

所以我尝试使用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

编辑:

似乎不安全的版本并不总是正确的, 如果它是一行它不会计算它,试图解决它而不会使它数太多;(

1 个答案:

答案 0 :(得分:3)

你的第二个实现似乎没问题,但是学习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;
}
由于对整个字符串进行一次评估,可能甚至更快。