这就是我现在正在使用的内容,但我很惊讶为什么CPU分析器将此作为瓶颈显示,而我的程序中还有许多其他相当昂贵的比较。
private bool IsAscii(char c)
{
return ((int)c < 128);
}
此函数用于日志处理程序,因此在紧密循环内调用日志中的每个字符。 (但是Char.IsLetterOrDigit()等其他函数也是如此,这些函数看起来并不昂贵。
我也尝试了一些变化,它们都比上面显示的稍慢或具有相似的性能。我不知道我是不是在做一些根本性的错误,因为我是C#的新手。
变体: -
// similar
private bool IsAscii(char c)
{
return (c < 128);
}
-
// slower
private bool IsAscii(char c)
{
return (Convert.ToInt32(c) < 128);
}
-
// similar
private bool IsAscii(char c)
{
return ((c & (~0x7f)) == 0);
}
-
// slower
// class member
private char asciiend = Char.ConvertFromUtf32(128)[0];
private bool IsAscii(char c)
{
return (c.CompareTo(asciiend) < 0);
}
-
答案 0 :(得分:2)
首先,您可能希望将其设为静态方法。毕竟,它不依赖于状态,并且可以删除无效检查。我希望JIT编译器能够聪明地看到它不需要它,但你永远不会知道。
答案 1 :(得分:1)
尝试手动内联。如果这样做更快,您可能只需要在呼叫成为瓶颈的地方手动内联它。
请注意,.NET Framework 4.5引入了MethodImplOptions.AggressiveInlining
。
答案 2 :(得分:0)
我唯一的猜测是你的函数没有被抖动所记忆,所以你大部分时间都花在函数调用上,而不是执行函数本身(我真的看不出你如何改进)。
尝试构建发布版本并添加一些自制的分析(使用Stopwatch
)来衡量您浏览大型日志文件所需的时间。运行它而不将其附加到Visual Studio(从外部或通过CTRL-F5启动它)。如果我的预感是正确的,你会发现性能会大幅提升,因为抖动可以自由地内联。
您还可以指示抖动在调试器下运行时执行其优化。切换到发布版本,转到工具|选项|调试|常规并取消选中“在模块加载时抑制JIT优化”。
一旦你解决了性能问题,你真的希望IsAscii成为Char类型的扩展方法 - 它更有意义(但不会解决你的性能问题)
答案 3 :(得分:-1)
如何使用System.Text
中的Encoding
对象?
String ascii = Encoding.ASCII.GetString(Encoding.ASCII.GetBytes(originalString));
虽然我不是100%肯定我知道意图是什么,或者这是一个可行的选择。