2011-11-25 71 views
5


我在一些我想优化的代码中发现了这个。 这里是snipet:这是一个正常的Java正则表达式行为吗?

tempString = bigBuffer.replaceAll("\\n", ""); 
tempString = tempString.replaceAll("\\t", ""); 

然后,我决定明智地使用正则表达式和我这样做:

tempString = bigBuffer.replaceAll("[\\n\\t]", ""); 

后来朋友告诉我,做这个:

tempString = bigBuffer.replaceAll("\\n|\\t", ""); 

由于我想知道我的更改的结果,我做了一个测试来验证它是否是一个很好的优化。所以,(java版本“1.6.0_27”)的结果是第一个代码是引用100%。

随着管道它是121%,所以它需要更多的时间来执行任务。

用方括号表示它是52%,因此执行该任务所用的时间较少。

为什么正则表达式应该是相同的?

马丁

+0

为什么它应该是相同的? – BoltClock

+0

我认为它应该是相同的,因为它做同样的事情。当管道使用单个字符时,编译器可能需要优化。 – Martin

回答

4

第一代码片段看起来通过bigBuffer两次,第一次更换的新生产线,并第二次更换的标签。

第二个代码片段仅搜索bigBuffer一次,检查每个字符是否是其中一个。这只会在一半的时间内完成速度。

第三位的代码片段可能编译得不好,导致第一个代码算法的版本特别差,尽管我没有仔细检查通过正则表达式编译的路径。

虽然在测试上出色的工作。相对时间(基于百分比)是有用的,绝对时间(毫秒或某些这样的)不是。

2

一般来说,角色类([abc])往往比等效替换更有效率(a|b|c),所以我不知道你的朋友为什么会这么建议。但是在Java中,只匹配拉丁语1的所有字符(即前256个Unicode代码点)的字符类进一步优化。这可能就是为什么你会看到第二和第三种技术之间的巨大差异。

同样,这只是Java。在Perl中,我希望交替和字符类之间的差异可以忽略不计,它是一个更成熟的实现。而在grep中,无论您使用三种方法中的哪一种,都可能难以衡量差异 - 这就是那么快。

但是,作为一个经验法则,如果您在使用字符类或交替之间进行选择,则应该更喜欢字符类。这可能不会更快,但它绝对不会变慢。如果使用不当,交替会对性能造成灾难性影响。

+0

感谢您的经验法则,我会确保我的朋友知道它。 – Martin