Wil*_*zel 5 java string performance
为什么indexOf比contains后者仅仅是第一个的包装要快得多?
来自Java API的代码:
public boolean contains(CharSequence s) {
return indexOf(s.toString()) > -1;
}
Run Code Online (Sandbox Code Playgroud)
这个帖子中选择的答案显示了一个简短的测试,它显示了差异.
此线程中选择的答案表明附加方法调用的开销无关紧要.那么,为什么差异呢?
请阅读我的编辑:几乎每个人都说微基准是有缺陷的.奇怪的是,它完全反映了我的用例.
实际上,我并不怀疑这indexOf比contains(对于我的用例)更快,我只想知道原因.
我的意图是永远不要写基准!我只是在寻找最有效的方法来测试一个字符串是否包含另一个字符串(对于我的应用程序而言,它与基准测试无关,而是"真实情况").
Sve*_*rev 11
该contains方法实现为:
public boolean contains(CharSequence s) {
return indexOf(s.toString()) > -1;
}
Run Code Online (Sandbox Code Playgroud)
这意味着如果CharSequence s不是a ,它可能会更慢,java.lang.String因为调用s.toString()将导致新字符串实例的分配和初始化.如果s是一个字符串 - 那么就不应该有任何可衡量的差异.
PS:这里的测试是有缺陷的:https://stackoverflow.com/a/18340277/2588800 Java最初以"解释"模式执行,这很慢,当它检测到一段代码被执行了很多次,它将它编译为本机代码以加快速度(阅读有关JIT编译的内容).
正如您可以看到contains内部调用indexOf,这意味着indexOf最终将编译为本机.因此,当他测试indexOf(注意他之后测试它contains)时,它可能已经被编译为本机代码.这就是时差的原因.尝试颠倒那些测试的顺序 - 首先测试indexOf然后contains我打赌你会看到相反的结果.
Benchmark Mode Cnt Score Error Units
StringSearchBenchmark.testContains thrpt 500 22,071 ± 0,269 ops/us
StringSearchBenchmark.testIndexOf thrpt 500 22,654 ± 0,233 ops/us
Run Code Online (Sandbox Code Playgroud)
正如您所看到的,差异可以忽略不计,可能会被系统上的其他方法调用(indexOf() + toString())和负载所淹没.
源代码:
@Fork(1)
@State(Scope.Benchmark)
@OutputTimeUnit(TimeUnit.MICROSECONDS)
@Measurement(iterations = 500, time = 50, timeUnit = TimeUnit.MILLISECONDS)
@Warmup(iterations = 10)
@BenchmarkMode(Mode.Throughput)
public class StringSearchBenchmark {
private static final String STATE = "absdefghijklmnopqrstuvwxyzabsdefghijklmnopqrstuvwxyzabsdefghijklmnopqrstuvwxyzabsdefghijklmnopqrstuvwxyz";
private static final String SEARCH_TERM = "abcd";
@Benchmark
public void testContains(Blackhole sink) {
sink.consume(STATE.contains(SEARCH_TERM));
}
@Benchmark
public void testIndexOf(Blackhole sink) {
sink.consume(STATE.indexOf(SEARCH_TERM));
}
}
Run Code Online (Sandbox Code Playgroud)