C# 计数行,这种不安全的方法有效吗?
所以我尝试了一个C# 计数行,这种不安全的方法有效吗?,c#,unsafe,C#,Unsafe,所以我尝试了一个不安全的快速方法来计算行数。 我以前使用过StringReader,但我想看看我是否可以做得更快 那么这段代码有效吗,它似乎有效,但看起来有点混乱 我对C#pointers非常陌生,所以我可能做了一些不好的事情 原始方法: //Return number of (non Empty) lines private static int getLineCount(string input) { int lines = 0; string line = null;
不安全的快速方法来计算行数。
我以前使用过StringReader
,但我想看看我是否可以做得更快
那么这段代码有效吗,它似乎有效,但看起来有点混乱
我对C#pointers非常陌生,所以我可能做了一些不好的事情
原始方法:
//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;
}
}
编辑:
似乎不安全的版本并不总是正确的,
如果是一条线,它就不会算数,一直在努力解决它,而不会让它算得太多;(你的第二个实现似乎不错,但是不要太多的学习<代码>不安全< /COD>,它在C语言中没有被广泛使用,也不是指针。这是接近C++的。这两种方法之间的时间差可能来自于避免垃圾回收器收集方法内的任何内存,直到完成为止。(因为固定了关键字)
很少使用不安全的是因为C#在已经定义的方法中提供了很多可读性和易用性,比如在您的案例中:
//Return number of (non Empty) lines
private static int getLineCount(string input)
{
return Regex.Matches(input, Environment.NewLine).Count;
}
这可能会更快,因为一次计算整个字符串。您复杂的方法真的会使您的操作更快吗?在我的测试中,是的,从大约“700ms”到大约“300-400ms”我认为。描述有效?如果你问它是否有效,那么你不应该测试它吗?这可能应该被移动到。此外,我认为这段代码需要将整个文件加载到内存中,如果要显式地计算字符串中的行数,这是可以的,但是如果我们谈论的是大文件,这是次优的。(编辑以添加最后一句)@Jim,我的意思是(不记得了)。我发布了基准测试。L-Four,不是真的,它更多的是为了学习指针和娱乐:)new StringReader(input)
从字符串创建一个阅读器,然后reader.ReadToEnd()
返回字符串。似乎没有必要。@Magnus先生,你说得很对,我已经更新了我的答案。值得的是,我做了一个测试。Regex-AVG=20.9546,MIN=20.6002,MAX=21.6283,总计00.210-AVG=1.61361,MIN=1.589,MAX=1.6748,总计00。016@Zerowalker怎么样:foreach(输入中的变量c)if(c=='\n')lines++;
?@Zerowalker您是否在没有安装调试程序的版本配置中测试了它们?这听起来像是一个很大的区别,但同样,这是一种罕见的情况,对于人类来说,在程序的正常执行中感受到这种差异是非常罕见的。这种安全程序的简单优点是它的可维护性,这是非常重要的与几毫秒相比很重要。
//Return number of (non Empty) lines
private static int getLineCount(string input)
{
return Regex.Matches(input, Environment.NewLine).Count;
}