package com.bellsw.simple; import java.util.concurrent.TimeUnit; import java.math.BigInteger; import java.lang.reflect.Method; import org.openjdk.jmh.annotations.Benchmark; import org.openjdk.jmh.annotations.BenchmarkMode; import org.openjdk.jmh.annotations.Level; import org.openjdk.jmh.annotations.Measurement; import org.openjdk.jmh.annotations.Mode; import org.openjdk.jmh.annotations.OutputTimeUnit; import org.openjdk.jmh.annotations.Param; import org.openjdk.jmh.annotations.Scope; import org.openjdk.jmh.annotations.Setup; import org.openjdk.jmh.annotations.State; import org.openjdk.jmh.annotations.Warmup; @Warmup(iterations = 2) @Measurement(iterations = 5) @BenchmarkMode(Mode.AverageTime) @OutputTimeUnit(TimeUnit.NANOSECONDS) @State(Scope.Benchmark) public class BigIntegerBench { static final int K = 0xCAFEBABE; // any int for multiplier value static final int OFFSET = 0; // we'll go from the start of array @Param({"1", "2", "3", "10", "50", "90", "127"}) int size; BigInteger bi; Method squareMethod = null; Method mulAddMethod = null; Method implSquareToLen = null; Method implMultiplyToLen = null; int[] out; int[] in; @Setup(Level.Trial) public void init() { try { squareMethod = BigInteger.class.getDeclaredMethod("square"); mulAddMethod = BigInteger.class.getDeclaredMethod("mulAdd", int[].class, int[].class, int.class, int.class, int.class); implMultiplyToLen = BigInteger.class.getDeclaredMethod("implMultiplyToLen", int[].class, int.class, int[].class, int.class, int[].class); implSquareToLen = BigInteger.class.getDeclaredMethod("implSquareToLen", int[].class, int.class, int[].class, int.class); } catch (ReflectiveOperationException roe) { throw new AssertionError("Reflection exception: " + roe, roe); } squareMethod.setAccessible(true); mulAddMethod.setAccessible(true); implMultiplyToLen.setAccessible(true); implSquareToLen.setAccessible(true); byte[] src = new byte[4 * size]; for(int i = 0; i < src.length; i++) { src[i] = (byte)(0xFF); } bi = new BigInteger(1, src); out = new int[2 * size]; for (int i = 0; i < 2 * size; i++) { out[i] = i; // anything is fine } in = new int[size]; for (int i = 0; i < size; i++) { in[i] = i; // anything is fine } } @Benchmark public Object squareReflect() throws ReflectiveOperationException { return squareMethod.invoke(bi); } @Benchmark public Object mulAddReflect() throws ReflectiveOperationException { return mulAddMethod.invoke(null, out, in, OFFSET, size, K); } @Benchmark public Object implSquareToLenReflect() throws ReflectiveOperationException { return implSquareToLen.invoke(null, in, in.length, out, out.length); } @Benchmark public Object implMutliplyToLenReflect() throws ReflectiveOperationException { return implMultiplyToLen.invoke(null, in, in.length, in, in.length, out); } }