【发布时间】:2009-01-06 11:30:58
【问题描述】:
我正在编写一个高性能解析器,在我看来Int32.Parse 可能太慢了。我写了一个假设正确输入的简单版本,它的性能要好得多。那么我应该创建自己的版本吗?还是已经有另一种更快的方法可用?
我的方法是这样的:
// parse simple int, assuming relatively correct input (i.e. all digits)
public static int ParseInt32Simply(string str) {
if (str == null) throw new ArgumentNullException("str");
if (str.Length == 0) throw new ArgumentException("str is empty");
int sign = 1, index = 0;
if (str[0] == '-') { sign = -1; index = 1; }
else if (str[0] == '+') { index = 1; }
int result = 0;
for (; index < str.Length; ++index) {
result = 10 * result + (str[index] - '0');
}
if (result < 0) throw new OverflowException(str + " is too large for Int32");
return result * sign;
}
我的结果与内置的等效结果非常不同:
Int32.Parse took 8.2775453 seconds
ParseInt32Simply took 0.6511523 seconds
Int32.Parse took 6.7625807 seconds
ParseInt32Simply took 0.4677390 seconds
(在我的机器上运行 2500 万次迭代;P4 3 GHz,运行 VS 2008 SP1)
那么,我应该使用我的版本吗?或者我可以使用其他方法吗?
【问题讨论】:
-
由于整数运算本质上是未经检查的,所以运行时不会自动抛出溢出异常吗?即使没有,您的溢出检查不会只检测到一半的情况吗? (即没有飞回正数时)
-
对不起,我的意思是含蓄的,而不是固有的
-
请注意您的分析不会扭曲结果。如果您调用一个函数的次数足够多,则结果可能会因函数调用开销而出现偏差。
-
@DrJokepu:正如你所说,它是“未经检查的”,但这意味着运行时不会抛出异常(与“检查”相反)。至于一半的情况,我知道这一点。我会以不同的方式处理它,但我会保持示例简洁。
-
@cletus:我同时调用了我的函数和 Int32.Parse,所以函数调用开销是一样的。
标签: .net performance parsing