在C#中检查字符串后缀的最快方法是什么?
我需要检查一个特定术语的大型列表中的每个字符串(从5000到100000个项目).保证该术语永远不会嵌入字符串中.换句话说,如果字符串包含该术语,则它将位于字符串的末尾.该字符串也保证长于后缀.文化信息并不重要.
这些是针对100000个字符串执行的不同方法(其中一半具有后缀):
1. Substring Comparison - 13.60ms
2. String.Contains - 22.33ms
3. CompareInfo.IsSuffix - 24.60ms
4. String.EndsWith - 29.08ms
5. String.LastIndexOf - 30.68ms
Run Code Online (Sandbox Code Playgroud)
这些是平均时间.[编辑]忘了提到字符串也被放入单独的列表中,但这并不重要.它确实增加了运行时间.
在我的系统子字符串比较中(使用String.Substring方法提取字符串的结尾并将其与后缀术语进行比较)在针对100000字符串进行测试时始终是最快的.使用子字符串比较的问题是垃圾收集可以大大减慢它(比其他方法更多)因为String.Substring创建新的字符串..NET 4.0中的效果并不像3.5及更低版本那么糟糕,但它仍然很明显.在我的测试中,String.Substring在12000-13000个字符串集上执行得更慢.这在系统和实现之间显然会有所不同.
[编辑]基准代码:http: //pastebin.com/smEtYNYN
[编辑] FlyingStreudel的代码运行速度很快,但Jon Skeet建议将EndsWith与StringComparison.Ordinal结合使用似乎是最好的选择.
Jon*_*eet 19
如果这是检查100,000个字符串所需的时间,那真的重要吗?
我个人string.EndsWith认为它是最具描述性的:它确切地说明了你要测试的内容.
我有点怀疑它似乎表现最差但是......如果你可以发布你的基准代码,那将是非常有用的.(特别是,它真的不应该做那么多的工作string.Contains.)
您是否尝试过指定序数匹配?这可能会使它明显加快:
if (x.EndsWith(y, StringComparison.Ordinal))
Run Code Online (Sandbox Code Playgroud)
当然,除非你想要进行序数比较,否则你不应该这样做- 你期待文化敏感的比赛吗?(开发人员倾向于不考虑这类事情,我非常坚定地将自己纳入该类别.)
Eri*_*ert 14
乔恩是绝对正确的; 这可能不是苹果对苹果的比较,因为不同的字符串方法对于文化敏感性有不同的默认值.请确保您在每个中都获得了您想要的比较语义.
除了Jon的回答,我还要补充一点,相关的问题不是"哪个最快?" 而是"哪个太慢?" 您对此代码的性能目标是什么?最慢的方法仍然可以在比电影放映机前进到下一帧更短的时间内找到结果,显然这是人类无法察觉的.如果你的目标是搜索对用户来说是即时的,那么你就完成了; 任何这些方法都有效.如果您的目标是搜索时间不到一毫秒,那么这些方法都不起作用; 它们都是数量级太慢. 预算是多少?
我看了一下你的基准代码,坦率地说,看起来很狡猾.
你正在测量各种无关的东西以及你想要衡量的东西; 您正在测量foreach的成本和添加到列表中,这两个成本可能与您尝试测试的成本具有相同的数量级.
而且,你并没有抛弃第一轮; 记住,JIT编译器会在第一次通过循环时调用你调用的代码,它会很热并且准备第二次运行,因此你的结果将会出现偏差; 你在很多小东西上平均一个非常大的东西.在过去,当我这样做时,我发现了jit时间实际上占据了其他一切时间的情况.这是现实的吗?您是指测量jit时间,还是不应将其视为平均值的一部分?