在C#中实现IsAscii()的有效方法

时间:2012-03-05 21:51:06

标签: c# unicode char ascii

这就是我现在正在使用的内容,但我很惊讶为什么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);
}

-

4 个答案:

答案 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%肯定我知道意图是什么,或者这是一个可行的选择。