gpt4 book ai didi

java - 字符串:为什么 indexOf 比 contains 快很多?

转载 作者:搜寻专家 更新时间:2023-10-31 08:18:54 24 4
gpt4 key购买 nike

为什么 indexOfcontains 快得多,如果后者只是第一个的包装器?

来自 Java API 的代码:

public boolean contains(CharSequence s) {
return indexOf(s.toString()) > -1;
}

在这个 thread 中选择的答案显示了一个简短的测试,它显示了差异。

在这个 thread 中选择的答案声明额外方法调用的开销无关紧要。那么,为什么会有所不同?

请阅读我的编辑:几乎每个人都说微基准测试存在缺陷。奇怪的是,它恰好反射(reflect)了我的用例。

实际上,一开始我并不怀疑 indexOfcontains 快(对于我的用例),我只是想知道为什么。

我的意图从来不是写一个基准测试!我只是在寻找最有效的方法来测试一个字符串是否包含另一个字符串(对于我的应用程序,它与基准无关,而是“现实生活中的情况”)。

最佳答案

contains 方法实现为:

public boolean contains(CharSequence s) {
return indexOf(s.toString()) > -1;
}

这意味着如果 CharSequence s 不是 java.lang.String,它可能会更慢,因为调用 s.toString() 会导致新字符串实例的分配和初始化。如果 s 是一个字符串 - 那么应该没有任何可测量的差异。

PS:这里的测试有缺陷:https://stackoverflow.com/a/18340277/2588800Java 最初以“解释”模式执行,这非常慢,当它检测到一段代码被执行了很多次时,它会将其编译为 native 代码以加快速度(阅读 JIT 编译)。

如您所见,contains 在内部调用了 indexOf,这意味着 indexOf 最终将被编译为 native 。因此,当他测试 indexOf 时(注意他在 contains 之后测试它)它可能已经被编译为 native 代码。这就是时差的原因。尝试颠倒测试的顺序 - 首先测试 indexOf,然后测试 contains,我敢打赌您会看到相反的结果。

JMH 来救援

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

如您所见,差异可以忽略不计,可能是由额外的方法调用(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));
}
}

关于java - 字符串:为什么 indexOf 比 contains 快很多?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39035714/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com