简体   繁体   English

JMH静态最终字段作为参数

[英]JMH static final field as parameter

I see in JMH a popular problem with ConstantFold , but what if I have inverse problem. 我在JMH中看到ConstantFold的一个流行问题,但是如果我有反问题怎么办。 I need the static final field as parameter. 我需要静态的final字段作为参数。 For example, it's can be some constant variable for some algorithm. 例如,对于某些算法,它可以是一些常量。 But in java-doc I see: {@link Param} fields should be non-final fields.. I made test for the static parameter (with @Param annotation) and for the static final, and I see, that access to static final is ~1.5 - 2 times more productive. 但是在java-doc中,我看到:{@link Param}字段应该是非最终字段。.我测试了静态参数(带有@Param批注)和静态final,我看到了对static final的访问生产率提高约1.5-2倍。

I found a quick solution in 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);
}

Access to the "SURROGATE" parameter has performance, like to the final field. 就像最后一个字段一样,对“ SURROGATE”参数的访问具有性能。 But maybe I missed something, or do not know, maybe has another method to do it?! 但是,也许我错过了一些东西,或者不知道,也许还有另一种方法?! Or it will good point to make support it in future. 否则将来会提供支持将是不错的选择。

What exactly are you trying to accomplish? 您到底想完成什么? Overwriting static finals with horrible Reflection hacks? 用可怕的反射技巧覆盖static finals Good luck with that! 祝你好运! You need to follow the language rules, and initialize static final -s with static initializers. 您需要遵循语言规则,并使用静态初始化程序初始化static final -s。

You cannot easily parameterize the values there, because you cannot pass any arguments to static initializer, except for some custom System.getProperty calls, and that's the way it is usually accomplished. 您无法轻松地在那里设置值的参数,因为除了某些自定义System.getProperty调用之外,您无法将任何参数传递给静态初始值设定项,通常是通过这种方式完成的。 JMH does not expose any API to poll the "current" parameters that are usable in static final initializations. JMH不会公开任何API来轮询在静态最终初始化中可用的“当前”参数。

You might try to create a @State class with static , but not final field, put parameter over that field, and then very carefully trigger the initialization of another class that has static final field, that will query the static field in your first class. 可能会尝试创建一个带有static而不是final字段的@State类,将参数放在该字段上,然后非常小心地触发另一个具有static final字段的类的初始化,该类将查询您的第一个类中的static字段。 But, this is very fragile, and might have unforeseen consequences. 但是,这非常脆弱,可能会产生无法预料的后果。 Like, eg you would only be able to pull this off once per JVM, and every subsequent run in the same JVM will silently omit "reading" the @Param . 像,例如,您将只能在每个JVM中实现一次,并且随后在同一JVM中运行的所有操作都将默默地忽略“读取” @Param

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM