Support underscores in param values

Sergey Kuksenko sergey.kuksenko at oracle.com
Mon Jun 10 03:43:47 UTC 2019


I am just curious why such trick - @Param(""+100_000) - is not enough?


On 5/21/19 6:38 AM, Roman Leventov wrote:
> The following patch adds support for underscores in param values:
>
>    @Param("100_000")
>    public int n;
>
> --- /dev/null Thu Jan 01 00:00:00 1970 +0000
> +++
> b/jmh-core-ct/src/test/java/org/openjdk/jmh/ct/params/ParamUnderscoresTest.java
> Tue
> May 21 15:32:05 2019 +0200
> @@ -0,0 +1,65 @@
> +/*
> + * Copyright (c) 2019, Red Hat, Inc. All rights reserved.
> + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
> + *
> + * This code is free software; you can redistribute it and/or modify it
> + * under the terms of the GNU General Public License version 2 only, as
> + * published by the Free Software Foundation.  Oracle designates this
> + * particular file as subject to the "Classpath" exception as provided
> + * by Oracle in the LICENSE file that accompanied this code.
> + *
> + * This code is distributed in the hope that it will be useful, but WITHOUT
> + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
> + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
> + * version 2 for more details (a copy is included in the LICENSE file that
> + * accompanied this code).
> + *
> + * You should have received a copy of the GNU General Public License
> version
> + * 2 along with this work; if not, write to the Free Software Foundation,
> + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
> + *
> + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
> + * or visit www.oracle.com if you need additional information or have any
> + * questions.
> + */
> +package org.openjdk.jmh.ct.params;
> +
> +import org.junit.Test;
> +import org.openjdk.jmh.annotations.Benchmark;
> +import org.openjdk.jmh.annotations.Param;
> +import org.openjdk.jmh.annotations.Scope;
> +import org.openjdk.jmh.annotations.State;
> +import org.openjdk.jmh.ct.CompileTest;
> +
> + at State(Scope.Benchmark)
> +public class ParamUnderscoresTest {
> +
> +    @Param("1_00")
> +    public byte byteParam;
> +
> +    @Param("10_000")
> +    public short shortParam;
> +
> +    @Param("100_000")
> +    public int intParam;
> +
> +    @Param("0.999_999")
> +    public float floatParam;
> +
> +    @Param("100_000")
> +    public long longParam;
> +
> +    @Param("0.999_999")
> +    public double doubleParam;
> +
> +    @Benchmark
> +    public void test() {
> +
> +    }
> +
> +    @Test
> +    public void compileTest() {
> +        CompileTest.assertOK(this.getClass());
> +    }
> +
> +}
> diff -r 99d7b73cf1e3 -r 3ceecc6774f4
> jmh-core-ct/src/test/java/org/openjdk/jmh/ct/params/invalid/Int4Test.java
> --- /dev/null Thu Jan 01 00:00:00 1970 +0000
> +++
> b/jmh-core-ct/src/test/java/org/openjdk/jmh/ct/params/invalid/Int4Test.java Tue
> May 21 15:32:05 2019 +0200
> @@ -0,0 +1,50 @@
> +/*
> + * Copyright (c) 2019, Red Hat, Inc. All rights reserved.
> + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
> + *
> + * This code is free software; you can redistribute it and/or modify it
> + * under the terms of the GNU General Public License version 2 only, as
> + * published by the Free Software Foundation.  Oracle designates this
> + * particular file as subject to the "Classpath" exception as provided
> + * by Oracle in the LICENSE file that accompanied this code.
> + *
> + * This code is distributed in the hope that it will be useful, but WITHOUT
> + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
> + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
> + * version 2 for more details (a copy is included in the LICENSE file that
> + * accompanied this code).
> + *
> + * You should have received a copy of the GNU General Public License
> version
> + * 2 along with this work; if not, write to the Free Software Foundation,
> + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
> + *
> + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
> + * or visit www.oracle.com if you need additional information or have any
> + * questions.
> + */
> +package org.openjdk.jmh.ct.params.invalid;
> +
> +import org.junit.Test;
> +import org.openjdk.jmh.annotations.Benchmark;
> +import org.openjdk.jmh.annotations.Param;
> +import org.openjdk.jmh.annotations.Scope;
> +import org.openjdk.jmh.annotations.State;
> +import org.openjdk.jmh.ct.CompileTest;
> +
> + at State(Scope.Benchmark)
> +public class Int4Test {
> +
> +    @Param("_1")
> +    public int param;
> +
> +    @Benchmark
> +    public void test() {
> +
> +    }
> +
> +    @Test
> +    public void compileTest() {
> +        CompileTest.assertFail(this.getClass());
> +    }
> +
> +}
> diff -r 99d7b73cf1e3 -r 3ceecc6774f4
> jmh-core-ct/src/test/java/org/openjdk/jmh/ct/params/invalid/Int5Test.java
> --- /dev/null Thu Jan 01 00:00:00 1970 +0000
> +++
> b/jmh-core-ct/src/test/java/org/openjdk/jmh/ct/params/invalid/Int5Test.java Tue
> May 21 15:32:05 2019 +0200
> @@ -0,0 +1,50 @@
> +/*
> + * Copyright (c) 2019, Red Hat, Inc. All rights reserved.
> + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
> + *
> + * This code is free software; you can redistribute it and/or modify it
> + * under the terms of the GNU General Public License version 2 only, as
> + * published by the Free Software Foundation.  Oracle designates this
> + * particular file as subject to the "Classpath" exception as provided
> + * by Oracle in the LICENSE file that accompanied this code.
> + *
> + * This code is distributed in the hope that it will be useful, but WITHOUT
> + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
> + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
> + * version 2 for more details (a copy is included in the LICENSE file that
> + * accompanied this code).
> + *
> + * You should have received a copy of the GNU General Public License
> version
> + * 2 along with this work; if not, write to the Free Software Foundation,
> + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
> + *
> + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
> + * or visit www.oracle.com if you need additional information or have any
> + * questions.
> + */
> +package org.openjdk.jmh.ct.params.invalid;
> +
> +import org.junit.Test;
> +import org.openjdk.jmh.annotations.Benchmark;
> +import org.openjdk.jmh.annotations.Param;
> +import org.openjdk.jmh.annotations.Scope;
> +import org.openjdk.jmh.annotations.State;
> +import org.openjdk.jmh.ct.CompileTest;
> +
> + at State(Scope.Benchmark)
> +public class Int5Test {
> +
> +    @Param("1_")
> +    public int param;
> +
> +    @Benchmark
> +    public void test() {
> +
> +    }
> +
> +    @Test
> +    public void compileTest() {
> +        CompileTest.assertFail(this.getClass());
> +    }
> +
> +}
> diff -r 99d7b73cf1e3 -r 3ceecc6774f4
> jmh-core/src/main/java/org/openjdk/jmh/generators/core/NumericParams.java
> --- /dev/null Thu Jan 01 00:00:00 1970 +0000
> +++
> b/jmh-core/src/main/java/org/openjdk/jmh/generators/core/NumericParams.java Tue
> May 21 15:32:05 2019 +0200
> @@ -0,0 +1,46 @@
> +/*
> + * Copyright (c) 2019, Red Hat, Inc. All rights reserved.
> + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
> + *
> + * This code is free software; you can redistribute it and/or modify it
> + * under the terms of the GNU General Public License version 2 only, as
> + * published by the Free Software Foundation.  Oracle designates this
> + * particular file as subject to the "Classpath" exception as provided
> + * by Oracle in the LICENSE file that accompanied this code.
> + *
> + * This code is distributed in the hope that it will be useful, but WITHOUT
> + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
> + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
> + * version 2 for more details (a copy is included in the LICENSE file that
> + * accompanied this code).
> + *
> + * You should have received a copy of the GNU General Public License
> version
> + * 2 along with this work; if not, write to the Free Software Foundation,
> + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
> + *
> + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
> + * or visit www.oracle.com if you need additional information or have any
> + * questions.
> + */
> +package org.openjdk.jmh.generators.core;
> +
> +import java.util.regex.Pattern;
> +
> +public final class NumericParams {
> +
> +    private static final Pattern UNDERSCORE_BETWEEN_DIGITS =
> +            Pattern.compile("(?<=[0-9])_(?=[0-9])");
> +
> +    /**
> +     * This method needs to be public because accesses are generated in
> {@link
> +     * StateObject#getParamAccessor}.
> +     */
> +    public static String removeJava7LiteralUnderscores(String
> numericLiteral) {
> +        // Such replacement doesn't guarantee strict compliancy with JDK,
> but in practice it's just
> +        // fine to allow underscores in numeric values for parameters.
> +        return
> UNDERSCORE_BETWEEN_DIGITS.matcher(numericLiteral).replaceAll("");
> +    }
> +
> +
> +    private NumericParams() {}
> +}
> diff -r 99d7b73cf1e3 -r 3ceecc6774f4
> jmh-core/src/main/java/org/openjdk/jmh/generators/core/StateObject.java
> ---
> a/jmh-core/src/main/java/org/openjdk/jmh/generators/core/StateObject.java Fri
> May 17 10:44:26 2019 -0700
> +++
> b/jmh-core/src/main/java/org/openjdk/jmh/generators/core/StateObject.java Tue
> May 21 15:32:05 2019 +0200
> @@ -117,29 +117,31 @@
>           if (type.equalsIgnoreCase("java.lang.String")) {
>               return "control.getParam(\"" + name + "\")";
>           }
> +        String removeUnderscores =
> +                NumericParams.class.getName() +
> ".removeJava7LiteralUnderscores(";
>           if (type.equalsIgnoreCase("boolean") ||
> type.equalsIgnoreCase("java.lang.Boolean")) {
>               return "Boolean.valueOf(control.getParam(\"" + name + "\"))";
>           }
>           if (type.equalsIgnoreCase("byte") ||
> type.equalsIgnoreCase("java.lang.Byte")) {
> -            return "Byte.valueOf(control.getParam(\"" + name + "\"))";
> +            return "Byte.valueOf(" + removeUnderscores +
> "control.getParam(\"" + name + "\")))";
>           }
>           if (type.equalsIgnoreCase("char") ||
> type.equalsIgnoreCase("java.lang.Character")) {
>               return "(control.getParam(\"" + name + "\")).charAt(0)";
>           }
>           if (type.equalsIgnoreCase("short") ||
> type.equalsIgnoreCase("java.lang.Short")) {
> -            return "Short.valueOf(control.getParam(\"" + name + "\"))";
> +            return "Short.valueOf(" + removeUnderscores +
> "control.getParam(\"" + name + "\")))";
>           }
>           if (type.equalsIgnoreCase("int") ||
> type.equalsIgnoreCase("java.lang.Integer")) {
> -            return "Integer.valueOf(control.getParam(\"" + name + "\"))";
> +            return "Integer.valueOf(" + removeUnderscores +
> "control.getParam(\"" + name + "\")))";
>           }
>           if (type.equalsIgnoreCase("float") ||
> type.equalsIgnoreCase("java.lang.Float")) {
> -            return "Float.valueOf(control.getParam(\"" + name + "\"))";
> +            return "Float.valueOf(" + removeUnderscores +
> "control.getParam(\"" + name + "\")))";
>           }
>           if (type.equalsIgnoreCase("long") ||
> type.equalsIgnoreCase("java.lang.Long")) {
> -            return "Long.valueOf(control.getParam(\"" + name + "\"))";
> +            return "Long.valueOf(" + removeUnderscores +
> "control.getParam(\"" + name + "\")))";
>           }
>           if (type.equalsIgnoreCase("double") ||
> type.equalsIgnoreCase("java.lang.Double")) {
> -            return "Double.valueOf(control.getParam(\"" + name + "\"))";
> +            return "Double.valueOf(" + removeUnderscores +
> "control.getParam(\"" + name + "\")))";
>           }
>
>           // assume enum
> diff -r 99d7b73cf1e3 -r 3ceecc6774f4
> jmh-core/src/main/java/org/openjdk/jmh/generators/core/StateObjectHandler.java
> ---
> a/jmh-core/src/main/java/org/openjdk/jmh/generators/core/StateObjectHandler.java
> Fri
> May 17 10:44:26 2019 -0700
> +++
> b/jmh-core/src/main/java/org/openjdk/jmh/generators/core/StateObjectHandler.java
> Tue
> May 21 15:32:05 2019 +0200
> @@ -441,7 +441,7 @@
>           }
>           if (typeName.equals("byte") || typeName.equals("java.lang.Byte")) {
>               try {
> -                Byte.valueOf(val);
> +
> Byte.valueOf(NumericParams.removeJava7LiteralUnderscores(val));
>                   return true;
>               } catch (NumberFormatException nfe) {
>               }
> @@ -451,35 +451,35 @@
>           }
>           if (typeName.equals("short") ||
> typeName.equals("java.lang.Short")) {
>               try {
> -                Short.valueOf(val);
> +
> Short.valueOf(NumericParams.removeJava7LiteralUnderscores(val));
>                   return true;
>               } catch (NumberFormatException nfe) {
>               }
>           }
>           if (typeName.equals("int") ||
> typeName.equals("java.lang.Integer")) {
>               try {
> -                Integer.valueOf(val);
> +
> Integer.valueOf(NumericParams.removeJava7LiteralUnderscores(val));
>                   return true;
>               } catch (NumberFormatException nfe) {
>               }
>           }
>           if (typeName.equals("float") ||
> typeName.equals("java.lang.Float")) {
>               try {
> -                Float.valueOf(val);
> +
> Float.valueOf(NumericParams.removeJava7LiteralUnderscores(val));
>                   return true;
>               } catch (NumberFormatException nfe) {
>               }
>           }
>           if (typeName.equals("long") || typeName.equals("java.lang.Long")) {
>               try {
> -                Long.valueOf(val);
> +
> Long.valueOf(NumericParams.removeJava7LiteralUnderscores(val));
>                   return true;
>               } catch (NumberFormatException nfe) {
>               }
>           }
>           if (typeName.equals("double") ||
> typeName.equals("java.lang.Double")) {
>               try {
> -                Double.valueOf(val);
> +
> Double.valueOf(NumericParams.removeJava7LiteralUnderscores(val));
>                   return true;
>               } catch (NumberFormatException nfe) {
>               }
> diff -r 99d7b73cf1e3 -r 3ceecc6774f4
> jmh-core/src/test/java/org/openjdk/jmh/generators/core/NumericParamsTest.java
> --- /dev/null Thu Jan 01 00:00:00 1970 +0000
> +++
> b/jmh-core/src/test/java/org/openjdk/jmh/generators/core/NumericParamsTest.java
> Tue
> May 21 15:32:05 2019 +0200
> @@ -0,0 +1,38 @@
> +/*
> + * Copyright (c) 2019, Red Hat, Inc. All rights reserved.
> + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
> + *
> + * This code is free software; you can redistribute it and/or modify it
> + * under the terms of the GNU General Public License version 2 only, as
> + * published by the Free Software Foundation.  Oracle designates this
> + * particular file as subject to the "Classpath" exception as provided
> + * by Oracle in the LICENSE file that accompanied this code.
> + *
> + * This code is distributed in the hope that it will be useful, but WITHOUT
> + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
> + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
> + * version 2 for more details (a copy is included in the LICENSE file that
> + * accompanied this code).
> + *
> + * You should have received a copy of the GNU General Public License
> version
> + * 2 along with this work; if not, write to the Free Software Foundation,
> + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
> + *
> + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
> + * or visit www.oracle.com if you need additional information or have any
> + * questions.
> + */
> +package org.openjdk.jmh.generators.core;
> +
> +import org.junit.Assert;
> +import org.junit.Test;
> +
> +public class NumericParamsTest {
> +
> +    @Test
> +    public void testRemoveJava7LiteralUnderscores() {
> +        Assert.assertEquals("10",
> NumericParams.removeJava7LiteralUnderscores("1_0"));
> +        Assert.assertEquals("0.99",
> NumericParams.removeJava7LiteralUnderscores("0.9_9"));
> +        Assert.assertEquals("10.0",
> NumericParams.removeJava7LiteralUnderscores("1_0.0"));
> +    }
> +}


More information about the jmh-dev mailing list