JMH静态最终字段作为参数

时间:2015-11-03 09:01:04

标签: java parameters final jmh

我在JMH中看到了ConstantFold的一个流行问题,但如果我遇到反问题怎么办?我需要静态最终字段作为参数。例如,对于某些算法,它可以是一些常量变量。 但是在java-doc中我看到:{@ link Param}字段应该是非final字段.. 我对静态参数(使用@Param注释)和静态final进行了测试,我看到,对静态final的访问是高效率的1.5到2倍。

我在反思中找到了一个快速解决方案:

private static final int SURROGATE = Runtime.getRuntime().availableProcessors(); //example
private static final Field SURROGATE_FIELD;
private static final String MODIFIERS_FIELD = "modifiers";
private static final ReflectionFactory reflection =
        ReflectionFactory.getReflectionFactory();
private static final FieldAccessor SURROGATE_FIELD_ACCESSOR;

static {
    try {
        SURROGATE_FIELD = ConstantFinalFieldBench.class.getDeclaredField("SURROGATE");
        SURROGATE_FIELD.setAccessible(true);
        Field modifiersField =
                Field.class.getDeclaredField(MODIFIERS_FIELD);
        modifiersField.setAccessible(true);
        int modifiers = modifiersField.getInt(SURROGATE_FIELD);
        modifiers &= ~Modifier.FINAL;
        modifiersField.setInt(SURROGATE_FIELD, modifiers);
        SURROGATE_FIELD_ACCESSOR = reflection.newFieldAccessor(
                SURROGATE_FIELD, false
        );
    } catch (Exception ex) {
        throw new Error(ex);
    }
}

@Param({"10"})
private static int paramConst;


@Setup
public void init() throws IllegalAccessException {
    SURROGATE_FIELD_ACCESSOR.setInt(null, paramConst);
}

访问" SURROGATE"参数具有性能,就像最终字段一样。但也许我错过了一些东西,或者不知道,或许有其他方法可以做到这一点?!或者将来支持它会很好。

1 个答案:

答案 0 :(得分:1)

你到底想要完成什么?用可怕的反射黑客覆盖static finals?祝你好运!您需要遵循语言规则,并使用静态初始化程序初始化static final - 。

您无法轻松地对那里的值进行参数化,因为除了一些自定义System.getProperty调用之外,您无法将任何参数传递给静态初始值设定项,这就是通常完成的方式。 JMH不公开任何API来轮询静态最终初始化中可用的“当前”参数。

可能尝试使用@State创建static类,但不创建final字段,将参数放在该字段上,然后非常小心地触发初始化具有static final字段的另一个类,它将查询第一个类中的static字段。但是,这非常脆弱,可能会产生无法预料的后果。例如,例如你只能在每个JVM上关闭一次,并且在同一个JVM中的每次后续运行都会默默地省略“读取”@Param