@Param support for enum

Joe Kearney mail at joekearney.co.uk
Thu Jun 5 20:02:27 UTC 2014


Finally got a chance to look at this. Also my OCA got approved today, which
is exciting.

The only sensible place to expand the set of values seems to be in
Runner#explodeAllParams, as you pointed to, generating a BenchmarkRecord
for each value. In order to get the enum constants we'll need a handle on
the type token of the enum, which we can get through the type of the field,
which we can get through the type of the benchmark class.

I don't think that's currently available in Runner, nor through the
BenchmarkRecord. I think the simplest way of getting to this may be through
the generated code.

It seems that it would be easy to make this all accessible through the
BenchmarkRecord though, since that knows that name of the generated
benchmark class. That doesn't expose the class with the @Benchmark methods,
but it could in a number of ways:

1. store a type token explicitly, create this in the generator. Not sure
whether that would have any impact on those hundreds of padding fields,
guessing certainly not if static.
2. new generated method getting the supertype from the
generated MyBenchmarkClass_1_jmh_B1 inner class
3. new generated method just returning the type token
4. Let @Generated class implement some marker interface like
GeneratedBenchmarkRunner<Target>
5. Annotate the @Generated class with @BenchmarkTarget(MyBenchmark.class),
or something
6. store a type token at runtime of the actual type of the benchmark class,
which I suppose could be different if we're inheriting benchmark methods,
but since (as I understand) we generate a class for every benchmark, we
shouldn't have to worry about this.
7. Finally - parse the original type out of the name of the @Generated
class name. This would seem to require some seriously error-prone guesses
around underscores.

Once we can access the class token we can get the type of the field
reflectively given the field name, which is the param key.

At the moment I think option 3 is the cleanest; addition to the @Generated
class of a method like this (naming open to suggestions):
  public Class<?> getBenchmarkTargetType() { // or return Class<MyBenchmark>
​​
    return MyBenchmark.class;
  }

With a decision on this I think it seems straightforward, but I'd like your
opinion before adding anything to the generated code. There's plenty of
scope for testing this, and for beefing up the params tests more generally.

Thanks,
Joe



On 28 May 2014 20:59, Aleksey Shipilev <aleksey.shipilev at oracle.com> wrote:

> On 05/28/2014 11:54 PM, Joe Kearney wrote:
> > I started by copying the org.openjdk.jmh.ct.valid.EnumTest and removing
> > the value on the @Param, but the test didn't fail as I was expecting.
> > I'll dig around the tests a little more to understand what they're
> > doing, hoping to get some time on this over the next few days.
>
> org.openjdk.jmh.ct.* are compile-time tests. As of now, removing the
> argument from @Param would not fail in compile time, but will fail in
> runtime if parameter value is not specified.
>
> Runtime tests are in jmh-core-it, and org.openjdk.jmh.it.params.* tests
> are what you are looking for, although there is no runtime failure test,
> which you probably want to add for non-enum arguments.
>
> -Aleksey.
>
>


More information about the jmh-dev mailing list