Java 如何基准测试&x27&';vs';%';使用JMH正确地计算成本

Java 如何基准测试&x27&';vs';%';使用JMH正确地计算成本,java,benchmarking,jmh,Java,Benchmarking,Jmh,所以这里是我要测试的一件简单的事情,mod操作或a和1(假设幂为2)的速度更快-这就是hashMap在内部所做的。这是拼写正确的“测试”吗?我必须承认,jmh的内部结构,以及在检查了所有样本之后(我认为是第三次)编写正确的微基准测试,是一个相当大的挑战。:) 这篇博文详细介绍了这一点: 您的基准被破坏(比较看似无关的数量),因为您正在比较(非最终字段&常量)和(常量%非最终字段)。替换为(non_final_field1%non_final_field2)和(non_final_field1&(

所以这里是我要测试的一件简单的事情,mod操作或a和1(假设幂为2)的速度更快-这就是hashMap在内部所做的。这是拼写正确的“测试”吗?我必须承认,jmh的内部结构,以及在检查了所有样本之后(我认为是第三次)编写正确的微基准测试,是一个相当大的挑战。:)


这篇博文详细介绍了这一点:

您的基准被破坏(比较看似无关的数量),因为您正在比较(非最终字段&常量)和(常量%非最终字段)。替换为(non_final_field1%non_final_field2)和(non_final_field1&(non_final_field2-1)),其中non_final_field2是2的幂


在HashMap的上下文中,该值用于从数组中读取,博客文章也涵盖了这一方面的含义。

当然不是,
arg%33
!=<代码>(arg-1)和33。以
42
为例……你想写
arg%32
arg&(32-1)
?@AlekseyShipilev完全是我的错,复制了错误的代码。@Eugene:对不起,但怎么回事
32453667%arg
是一个真正的哈希函数吗<代码>(arg-1)&32453667应该做什么
32453667
既不是素数,也不是二的幂,也不是二减一的幂。什么。这个地狱。我很困惑。我告诉你:使用常数散列的测试不同于使用常数模的测试,也不同于使用非常数散列和模的测试。这些变体中的每一个都是“正确的”,从某种意义上说,它们衡量的是某种东西。但他们是在衡量你真正想要衡量的东西吗?只有你能回答。如果您不确定,请全部尝试。我所说的“尝试”是指“测量”和“分析”正在发生的事情以及它们产生不同/相同结果的原因。
   @State(Scope.Thread)
@BenchmarkMode(org.openjdk.jmh.annotations.Mode.AverageTime)
@OutputTimeUnit(TimeUnit.NANOSECONDS)
public class MeasureSpeedModuleVsAnd {

    public static void main(String[] args) throws Exception {
        Options opt = new OptionsBuilder()
                .include(MeasureSpeedModuleVsAnd.class.getSimpleName())
                .forks(1)
                .warmupIterations(1)
                .measurementIterations(5)
                .warmupTime(TimeValue.seconds(2))
                .build();

        new Runner(opt).run();

    }

    @Param({ "16", "32", "256", "1048576" /* 2 power of 10 */ })
    public int number_of_buckets;

    @Param({ "345984", "123456", "111", "98653" })
    public int hashcode;

    @Benchmark
    public int benchamark_modulo() {
        return hashcode % number_of_buckets;
    }

    @Benchmark
    public int benchmark_and() {
        return (number_of_buckets - 1) & hashcode;
    }
}