您的JMH测试不正确,因为您不使用该结果,因此
indexOfJIT编译器可以完全删除(或不能删除)该调用。在您的情况下,JIT编译器似乎确定
indexOf(String)没有副作用,因此完全删除了此调用,但对却没有这样做
indexOf(char)。始终使用结果(最简单的方法是从基准返回结果)。这是我的版本:
import java.util.*;import java.util.concurrent.TimeUnit;import org.openjdk.jmh.annotations.*;@State(Scope.Benchmark)@BenchmarkMode(Mode.AverageTime)@OutputTimeUnit(TimeUnit.NANOSECONDS)@Warmup(iterations = 5, time = 500, timeUnit = TimeUnit.MILLISECONDS)@Measurement(iterations = 10, time = 500, timeUnit = TimeUnit.MILLISECONDS)@Fork(3)public class IndexOfTest { private String str; private char c; private String s; @Setup public void setup() { str = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"; c = 'z'; s = "z"; } @Benchmark public int indexOfChar() { return str.indexOf('z'); } @Benchmark public int indexOfString() { return str.indexOf("z"); } @Benchmark public int indexOfCharIndirect() { return str.indexOf(c); } @Benchmark public int indexOfStringIndirect() { return str.indexOf(s); }}
我测试了同样的东西,但是增加了两个间接测试:从字段中加载搜索到的char或String时,因此在JIT编译期间其确切值是未知的。结果如下(Intel
x64):
# JMH 1.11.2 (released 27 days ago)# VM version: JDK 1.8.0_45, VM 25.45-b02Benchmark Mode Cnt Score Error UnitsIndexOfTest.indexOfChar avgt 30 25,364 ± 0,424 ns/opIndexOfTest.indexOfCharIndirect avgt 30 25,287 ± 0,210 ns/opIndexOfTest.indexOfString avgt 30 24,370 ± 0,100 ns/opIndexOfTest.indexOfStringIndirect avgt 30 27,198 ± 0,048 ns/op
如您所见,
indexOfChar无论直接访问还是间接访问,其执行方式都相同。该
indexOfString速度稍快于直接访问,但要慢一些间接的。那是因为
indexOf(String)是JVM固有的:它的Java代码实际上已被具有有效内联实现的JIT编译器所替代。对于在JIT编译时已知的常量字符串,可以生成更有效的代码。
通常,至少对于这样的短字符串没有太大的区别。因此,您可以将这些方法之一用于单个符号匹配。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)