我正在编写一个高性能的解析器,在我看来,它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万次迭代;运行VS 2008 SP1的P4 3 GHz)
那么,我应该使用我的版本吗?或者我可以使用另一种方法吗?
您是否已经分析了您的代码以确定ParseInt32实际上是瓶颈?除非你确定你会看到一个好处,否则我不会替换你正在编码的环境的"标准库"中的某些内容.
在.NET中Int32.Parse
是非常非常快,当它是成功的.
当它失败时会抛出异常 - 然后它非常慢,因为异常很慢.
您需要扩展测试 - 您需要检查时间是否与您需要的类似的好的和坏的字符串模式.
如果您非常确定所有字符串都是有效的int,那么Int32.Parse
就是要走的路.如果你怀疑任何可以忽略不计的几个都是有效的,那么使用起来要快得多Int32.TryParse
,而不是try-catch
在你的循环中.
通常,如果您try-catch
在循环使用之外Int32.Parse
- 您将获得异常并在第一次获得无效值时停止.
如果您try-catch
在循环内使用Int32.TryParse
而不是.
这两个Int32.Parse
和Int32.TryParse
是相当高度优化和相对成熟的-我希望他们是非常艰难的改善,除非你有专业的情况.