From d5fe8ea7ff0d7a4648bb5518b886d0e4a66ca34f Mon Sep 17 00:00:00 2001 From: Anish Date: Thu, 9 May 2019 15:31:50 +0200 Subject: [PATCH] add jmh bench marks for bloom filters --- scio-jmh/README.md | 17 +++++ .../scio/jmh/BloomFilterCreateBenchmark.scala | 70 +++++++++++++++++++ .../scio/jmh/BloomFilterQueryBenchmark.scala | 59 ++++++++++++++++ 3 files changed, 146 insertions(+) create mode 100644 scio-jmh/README.md create mode 100644 scio-jmh/src/test/scala/com/spotify/scio/jmh/BloomFilterCreateBenchmark.scala create mode 100644 scio-jmh/src/test/scala/com/spotify/scio/jmh/BloomFilterQueryBenchmark.scala diff --git a/scio-jmh/README.md b/scio-jmh/README.md new file mode 100644 index 0000000000..6ed4e5ea13 --- /dev/null +++ b/scio-jmh/README.md @@ -0,0 +1,17 @@ +# JMH benchmarks + +JMH based benchmarks for certain specific components in Scio. + +Getting started and running JMH benchmarks via sbt-shell: +``` +$ sbt +... +sbt:scio> project scio-jmh +sbt:scio-jmh> jmh:run -f1 -wi 2 -i 3 .*BloomFilter.*Benchmark.* +``` + +The options for `jmh:run` + - `-f1` Run with 1 fork + - `-wi 2` Run 2 warm up iterations + - `-i 3` Run 3 iterations + - `.*BloomFilter.*Benchmark.*` RegExp for Benchmark diff --git a/scio-jmh/src/test/scala/com/spotify/scio/jmh/BloomFilterCreateBenchmark.scala b/scio-jmh/src/test/scala/com/spotify/scio/jmh/BloomFilterCreateBenchmark.scala new file mode 100644 index 0000000000..f991afed6a --- /dev/null +++ b/scio-jmh/src/test/scala/com/spotify/scio/jmh/BloomFilterCreateBenchmark.scala @@ -0,0 +1,70 @@ +/* + * Copyright 2019 Spotify AB. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package com.spotify.scio.jmh + +import com.spotify.scio.util.{BloomFilter, BloomFilterAggregator, MutableBF} +import org.openjdk.jmh.annotations._ + +import scala.util.Random + +/** + * Benchmarks for com.spotify.scio.util.BloomFilter + * + * Creating a BF from a collection + */ +object BloomFilterCreateBenchmark { + def createRandomString(nbrOfStrings: Int, lengthOfStrings: Int): Seq[String] = + Seq.fill(nbrOfStrings)(Random.nextString(lengthOfStrings)) + + @State(Scope.Benchmark) + class BloomFilterState { + @Param(Array("100", "1000", "10000")) + var nbrOfElements: Int = 0 + + @Param(Array("0.01", "0.001")) + var falsePositiveRate: Double = 0 + + var randomStrings: Seq[String] = _ + + @Setup(Level.Trial) + def setup(): Unit = + randomStrings = createRandomString(nbrOfElements, 10) + + } +} + +@State(Scope.Benchmark) +class BloomFilterCreateBenchmark { + + import BloomFilterCreateBenchmark._ + + /** + * Create a bloom filter by aggregating on a monoid. + * This is the most efficient way to create the bloom filter. + */ + @Benchmark + def scioMutableBF(bloomFilterState: BloomFilterState): MutableBF[String] = { + val bfMonoid = + BloomFilter[String](bloomFilterState.nbrOfElements, bloomFilterState.falsePositiveRate) + val bfAggregator = BloomFilterAggregator(bfMonoid) + + val sBf = bloomFilterState.randomStrings.aggregate(bfAggregator.monoid.zero)(_ += _, _ ++= _) + sBf + } + +} diff --git a/scio-jmh/src/test/scala/com/spotify/scio/jmh/BloomFilterQueryBenchmark.scala b/scio-jmh/src/test/scala/com/spotify/scio/jmh/BloomFilterQueryBenchmark.scala new file mode 100644 index 0000000000..a67f17b0c7 --- /dev/null +++ b/scio-jmh/src/test/scala/com/spotify/scio/jmh/BloomFilterQueryBenchmark.scala @@ -0,0 +1,59 @@ +/* + * Copyright 2019 Spotify AB. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package com.spotify.scio.jmh + +import com.spotify.scio.util.{BloomFilter, MutableBF} +import com.twitter.algebird.ApproximateBoolean +import org.openjdk.jmh.annotations._ + +/** + * Benchmarks for com.spotify.scio.util.BloomFilter + * + * Querying for elements from a BloomFilter. + */ +object BloomFilterQueryBenchmark { + + @State(Scope.Benchmark) + class BloomFilterState { + + @Param(Array("100", "1000", "10000")) + var nbrOfElements: Int = 0 + + @Param(Array("0.001", "0.01")) + var falsePositiveRate: Double = 0 + + private[scio] var bf: MutableBF[String] = _ + + @Setup(Level.Trial) + def setup(): Unit = { + val randomStrings = + BloomFilterCreateBenchmark.createRandomString(nbrOfElements, 10) + bf = BloomFilter[String](nbrOfElements, falsePositiveRate) + .create(randomStrings: _*) + } + } +} + +@State(Scope.Benchmark) +class BloomFilterQueryBenchmark { + import BloomFilterQueryBenchmark._ + + @Benchmark + def scioBloomFilter(bloomFilterState: BloomFilterState): ApproximateBoolean = + bloomFilterState.bf.contains("1") +}