Reputation: 241
I see in JMH a popular problem with ConstantFold, but what if I have inverse problem. I need the static final field as parameter. 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.
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. 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.
Upvotes: 0
Views: 3099
Reputation: 18857
What exactly are you trying to accomplish? Overwriting static finals
with horrible Reflection hacks? Good luck with that! You need to follow the language rules, and initialize static final
-s with static initializers.
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. JMH does not expose any API to poll the "current" parameters that are usable in static final initializations.
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. But, this is very fragile, and might have unforeseen consequences. Like, e.g. 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
.
Upvotes: 1