java - JMH 静态最终字段作为参数

标签 java parameters final jmh

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

我在反射(reflection)中找到了一个快速解决方案:

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”参数具有性能,就像访问最终字段一样。但也许我错过了一些东西,或者不知道,也许有另一种方法可以做到这一点?!或者将来支持它会很好。

最佳答案

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

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

可能尝试创建一个带有static但不是final字段的@State类,放置参数覆盖该字段,然后非常小心地触发具有 static Final 字段的另一个类的初始化,该类将查询第一个字段中的 static 字段类(class)。但是,这是非常脆弱的,可能会产生不可预见的后果。就像,例如每个 JVM 只能完成一次此操作,并且同一 JVM 中的每次后续运行都会默默地省略“读取”@Param

关于java - JMH 静态最终字段作为参数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33494989/

相关文章:

java - 计算包括两个给定日期的天数

c# - 处理 1 或 2 或 3 值的存储过程

java - HTTP 状态 500 - 实例化 Servlet 类 java.reg.pkg.Hello 时出错

java - 如何从Mule批量发送消息到ActiveMQ

c - 如何将参数传递给clone()调用的函数?

java - "final int i"如何在 Java for 循环中工作?

java - Kotlin val 是否提供与 java final 相同的可见性保证?

java - Java 中继承的最终常量值?

java - 使用 boolean 值来声明重复单词的 true 或 false,而不使用循环结构

java - 使用另一个面板的值刷新 JPanel