From 2a0aefedc9027eae5ff50eb890a2d3d4e109980b Mon Sep 17 00:00:00 2001 From: i10416 Date: Sat, 4 Dec 2021 15:52:44 +0900 Subject: [PATCH] migrate caliper to jmh --- .../spire/benchmark/NaturalBenchmark.scala | 90 ++++++++++--------- .../scala/spire/benchmark/PowBenchmark.scala | 49 ++++++---- .../scala/spire/benchmark/RexBenchmark.scala | 30 ++++--- .../spire/benchmark/ZigguratBenchmarks.scala | 79 ++++++++++------ 4 files changed, 150 insertions(+), 98 deletions(-) diff --git a/benchmark/src/main/scala/spire/benchmark/NaturalBenchmark.scala b/benchmark/src/main/scala/spire/benchmark/NaturalBenchmark.scala index ef3df0429..dac382a25 100644 --- a/benchmark/src/main/scala/spire/benchmark/NaturalBenchmark.scala +++ b/benchmark/src/main/scala/spire/benchmark/NaturalBenchmark.scala @@ -15,62 +15,72 @@ package spire package benchmark -/* - -import scala.util.Random -import spire.math._ +import org.openjdk.jmh.annotations._ import spire.implicits._ - -import com.google.caliper.Param +import spire.math._ import java.lang.Math +import java.util.concurrent.TimeUnit +import scala.util.Random -object NaturalBenchmarks extends MyRunner(classOf[NaturalBenchmarks]) - -class NaturalBenchmarks extends MyBenchmark { - import spire.math.SafeLong.SafeLongAlgebra +import Arrays.init - //@Param(Array("8", "16", "32", "64", "96", "128", "192", "256")) - //@Param(Array("8")) +@BenchmarkMode(Array(Mode.AverageTime)) +@OutputTimeUnit(TimeUnit.MICROSECONDS) +@State(Scope.Thread) +class NaturalBenchmarks { @Param(Array("8", "16", "32", "64", "128")) var bits: Int = 0 - //@Param(Array("10", "15", "20")) + // @Param(Array("10", "15", "20")) @Param(Array("10")) var pow: Int = 0 - var size: Int = 0 - - var nats: Array[Natural] = _ - var bigints: Array[BigInt] = _ - var safes: Array[SafeLong] = _ + var nats: Array[Natural] = null + var bigints: Array[BigInt] = null + var safes: Array[SafeLong] = null - override def setUp(): Unit = { - size = Math.pow(2, pow).toInt + @Setup + def setUp(): Unit = { + val size = Math.pow(2, pow).toInt bigints = init(size)(BigInt(bits, Random)) nats = bigints.map(Natural(_)) safes = bigints.map(SafeLong(_)) } - def timeNaturalSum(reps: Int) = run(reps)(nats.qsum) - def timeBigIntSum(reps: Int) = run(reps)(bigints.qsum) - def timeSafeLongSums(reps: Int) = run(reps)(safes.qsum) - - def timeNaturalSumDoubles(reps: Int) = run(reps)(nats.map(n => n << 1).qsum) - def timeBigIntSumDoubles(reps: Int) = run(reps)(bigints.map(n => n << 1).qsum) - def timeSafeLongSumDoubles(reps: Int) = run(reps)(safes.map(n => n * 2).qsum) - - def timeNaturalSumSquares(reps: Int) = run(reps)(nats.map(n => n * n).qsum) - def timeBigIntSumSquares(reps: Int) = run(reps)(bigints.map(n => n * n).qsum) - def timeSafeLongSumSquares(reps: Int) = run(reps)(safes.map(n => n * n).qsum) - - def timeNaturalSumNormalized(reps: Int) = run(reps)(nats.map(n => n / UInt(10)).qsum) - def timeBigIntSumNormalized(reps: Int) = run(reps)(bigints.map(n => n / 10).qsum) - def timeSafeLongSumNormalized(reps: Int) = run(reps)(safes.map(n => n / 10).qsum) - - def timeNaturalMin(reps: Int) = run(reps)(nats.qmin) - def timeBigIntMin(reps: Int) = run(reps)(bigints.qmin) - def timeSafeLongMin(reps: Int) = run(reps)(safes.qmin) + @Benchmark + def timeNaturalSum() = nats.qsum + + @Benchmark + def timeBigIntSum() = bigints.qsum + @Benchmark + def timeSafeLongSums() = safes.qsum + + @Benchmark + def timeNaturalSumDoubles() = nats.map(n => n << 1).qsum + + @Benchmark + def timeBigIntSumDoubles() = bigints.map(n => n << 1).qsum + @Benchmark + def timeSafeLongSumDoubles() = safes.map(n => n * 2).qsum + @Benchmark + def timeNaturalSumSquares() = nats.map(n => n * n).qsum + @Benchmark + def timeBigIntSumSquares() = bigints.map(n => n * n).qsum + @Benchmark + def timeSafeLongSumSquares() = safes.map(n => n * n).qsum + + @Benchmark + def timeNaturalSumNormalized() = nats.map(n => n / UInt(10)).qsum + @Benchmark + def timeBigIntSumNormalized() = bigints.map(n => n / 10).qsum + @Benchmark + def timeSafeLongSumNormalized() = safes.map(n => n / 10).qsum + @Benchmark + def timeNaturalMin() = nats.qmin + @Benchmark + def timeBigIntMin() = bigints.qmin + @Benchmark + def timeSafeLongMin() = safes.qmin } - */ diff --git a/benchmark/src/main/scala/spire/benchmark/PowBenchmark.scala b/benchmark/src/main/scala/spire/benchmark/PowBenchmark.scala index 69bac18b5..835c291c5 100644 --- a/benchmark/src/main/scala/spire/benchmark/PowBenchmark.scala +++ b/benchmark/src/main/scala/spire/benchmark/PowBenchmark.scala @@ -15,26 +15,34 @@ package spire package benchmark -/* import scala.util.Random import Random._ +import org.openjdk.jmh.annotations._ +import java.util.concurrent.TimeUnit +import Arrays.init import spire.implicits._ -object PowBenchmarks extends MyRunner(classOf[PowBenchmarks]) - -class PowBenchmarks extends MyBenchmark { +@BenchmarkMode(Array(Mode.AverageTime)) +@OutputTimeUnit(TimeUnit.MICROSECONDS) +@State(Scope.Thread) +class PowBenchmarks { var longs: Array[Long] = null var ints: Array[Int] = null + var doubles: Array[Double] = null - override def setUp(): Unit = { - ints = init(200000)(nextInt) - longs = init(200000)(nextLong) + @Setup + def setUp(): Unit = { + val l = 200000 + ints = init(l)(nextInt) + longs = init(l)(nextLong) + doubles = init(l)(nextDouble) } - def timeLongPowForInt(reps:Int) = run(reps) { + @Benchmark + def timeLongPowForInt(): Int = { var t = 0 ints.foreach { n => t += spire.math.pow(n.toLong, 2.toLong).toInt @@ -42,7 +50,8 @@ class PowBenchmarks extends MyBenchmark { t } - def timeDoublePowForInt(reps:Int) = run(reps) { + @Benchmark + def timeDoublePowForInt(): Int = { var t = 0 ints.foreach { n => t += spire.math.pow(n.toDouble, 2.0).toInt @@ -50,15 +59,17 @@ class PowBenchmarks extends MyBenchmark { t } - def timeBigIntPowForInt(reps:Int) = run(reps) { + @Benchmark + def timeBigIntPowForInt(): Int = { var t = 0 ints.foreach { n => - t += (BigInt(n) pow 2).toInt + t += BigInt(n).pow(2).toInt } t } - def timeLongPowForLong(reps:Int) = run(reps) { + @Benchmark + def timeLongPowForLong(): Long = { var t = 0L longs.foreach { n => t += spire.math.pow(n, 2L) @@ -66,7 +77,8 @@ class PowBenchmarks extends MyBenchmark { t } - def timeDoublePowForLong(reps:Int) = run(reps) { + @Benchmark + def timeDoublePowForLong(): Long = { var t = 0L longs.foreach { n => t += spire.math.pow(n.toDouble, 2.0).toLong @@ -74,20 +86,21 @@ class PowBenchmarks extends MyBenchmark { t } - def timeBigIntPowForLong(reps:Int) = run(reps) { + @Benchmark + def timeBigIntPowForLong(): Long = { var t = 0L longs.foreach { n => - t += (BigInt(n) pow 2).toLong + t += BigInt(n).pow(2).toLong } t } - def timeDoublePowForDouble(reps:Int) = run(reps) { + @Benchmark + def timeDoublePowForDouble(): Double = { var t = 0.0 - longs.foreach { n => + doubles.foreach { n => t += spire.math.pow(n, 2.0) } t } } - */ diff --git a/benchmark/src/main/scala/spire/benchmark/RexBenchmark.scala b/benchmark/src/main/scala/spire/benchmark/RexBenchmark.scala index f7b67612d..a02f29b0a 100644 --- a/benchmark/src/main/scala/spire/benchmark/RexBenchmark.scala +++ b/benchmark/src/main/scala/spire/benchmark/RexBenchmark.scala @@ -15,31 +15,36 @@ package spire package benchmark - -/* import spire.implicits._ import spire.math._ - +import spire.benchmark.ArrayOrder +import Arrays.mkarray import scala.util.Random._ -import com.google.caliper.Param +import org.openjdk.jmh.annotations._ +import java.util.concurrent.TimeUnit -object RexBenchmarks extends MyRunner(classOf[RexBenchmarks]) - -class RexBenchmarks extends MyBenchmark with BenchmarkData { +@BenchmarkMode(Array(Mode.AverageTime)) +@OutputTimeUnit(TimeUnit.MICROSECONDS) +@State(Scope.Thread) +class RexBenchmarks { @Param(Array("10", "12", "14", "16", "18")) var pow: Int = 0 var fs: Array[Float] = null var ds: Array[Double] = null - override protected def setUp(): Unit = { + @Setup + def setUp(): Unit = { val size = spire.math.pow(2, pow).toInt - fs = mkarray(size, "random")(nextGaussian.toFloat) - ds = mkarray(size, "random")(nextGaussian) + fs = mkarray(size, ArrayOrder.Random)(nextGaussian.toFloat) + ds = mkarray(size, ArrayOrder.Random)(nextGaussian) } - def timeDirect(reps:Int): Unit = run(reps)(runDirect(fs, ds, 20)) - def timeGeneric(reps:Int): Unit = run(reps)(runGeneric(fs, ds, 20)) + @Benchmark + def timeDirect(): Unit = runDirect(fs, ds, 20) + + @Benchmark + def timeGeneric(): Unit = runGeneric(fs, ds, 20) def runDirect(a: Array[Float], b: Array[Double], n: Int): Double = { (for (i <- 2 to n by 2) yield nearlyMaxF(a, n) + nearlyMaxD(b, n)).sum @@ -115,4 +120,3 @@ class RexBenchmarks extends MyBenchmark with BenchmarkData { ai(k) } } - */ diff --git a/benchmark/src/main/scala/spire/benchmark/ZigguratBenchmarks.scala b/benchmark/src/main/scala/spire/benchmark/ZigguratBenchmarks.scala index 032ac54dc..0ed490394 100644 --- a/benchmark/src/main/scala/spire/benchmark/ZigguratBenchmarks.scala +++ b/benchmark/src/main/scala/spire/benchmark/ZigguratBenchmarks.scala @@ -15,52 +15,77 @@ package spire package benchmark +import java.util.concurrent.TimeUnit + +import org.openjdk.jmh.annotations._ +import spire.implicits._ -/* /** - * This is a benchmark comparing Marsaglias Polar Method implementation with the implementation of his Ziggurat algorithm. + * This is a benchmark comparing Marsaglias Polar Method implementation with the implementation of his Ziggurat + * algorithm. * - *

Reference: - * George Marsaglia, Wai Wan Tsang: - * "The Ziggurat Method for Generating Random Variables" + *

Reference: George Marsaglia, Wai Wan Tsang: "The Ziggurat Method for Generating Random Variables" * Journal of Statistical Software, Vol. 5, Issue 8, October 2000. * - * @see Ziggurat Paper - * @see Ziggurat algorithm @ Wikipedia - * @author Dušan Kysel + * @see + * Ziggurat Paper + * @see + * Ziggurat algorithm @ Wikipedia + * @author + * Dušan Kysel */ -object ZigguratBenchmarks extends MyRunner(classOf[ZigguratBenchmarks]) - -class ZigguratBenchmarks extends MyBenchmark with BenchmarkData { +@BenchmarkMode(Array(Mode.AverageTime)) +@OutputTimeUnit(TimeUnit.MICROSECONDS) +@State(Scope.Thread) +class ZigguratBenchmarks { val well512aRng: spire.random.Generator = spire.random.rng.Well512a.fromTime() val mg = new spire.random.MarsagliaGaussian[Double] val gaussDist = mg(0d, 1d) + @inline final def len = 10000000 - @inline final def nextLen = 10000000 - - def timePolarRNORGenerator(reps: Int) = run(reps) { - val rng = well512aRng - var t = 0d - cfor(0)(_ < nextLen, _ + 1)(_ => t += rng.nextGaussian()) + @Benchmark + def timePolarRNORGenerator(): Double = { + var total = 0d + var i = 0 + while (i < len) { + total += well512aRng.nextGaussian(0d, 1d) + i += 1 + } + total } - def timePolarRNORDist(reps: Int) = run(reps) { + @Benchmark + def timePolarRNORDist(): Double = { val rng = well512aRng - var t = 0d - cfor(0)(_ < nextLen, _ + 1)(_ => t += gaussDist(rng)) + var total = 0d + var i = 0 + while (i < len) { + total += gaussDist(rng) + i += 1 + } + total } - def timeZigguratRNOR(reps: Int) = run(reps) { + @Benchmark + def timeZigguratRNOR(): Double = { val rng = well512aRng - var t = 0d - cfor(0)(_ < nextLen, _ + 1)(_ => t += spire.random.Ziggurat.rnor(rng)) + var total = 0d + var i = 0 + while (i < len) { + total += spire.random.Ziggurat.rnor(rng) + } + total } - def timeZigguratREXP(reps: Int) = run(reps) { + @Benchmark + def timeZigguratREXP(): Double = { val rng = well512aRng - var t = 0d - cfor(0)(_ < nextLen, _ + 1)(_ => t += spire.random.Ziggurat.rexp(rng)) + var total = 0d + var i = 0 + while (i < len) { + total += spire.random.Ziggurat.rexp(rng) + } + total } } - */