Created
August 28, 2021 17:55
-
-
Save TheDIM47/c9def0e39b2014a07b22d770baad87a3 to your computer and use it in GitHub Desktop.
flatten benchmarks
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package benchmarks | |
import org.openjdk.jmh.annotations._ | |
import scala.util.Random | |
import java.util.concurrent.TimeUnit | |
import scala.annotation.tailrec | |
/* | |
[info] Benchmark (size) Mode Cnt Score Error Units | |
[info] EffFlattenBenchmark.benchEffFlatten 50 thrpt 5 2981.439 ± 165.839 ops/ms | |
[info] EffFlattenBenchmark.benchEffFlatten 100 thrpt 5 1438.206 ± 24.179 ops/ms | |
[info] EffFlattenBenchmark.benchEffFlatten 500 thrpt 5 321.286 ± 9.320 ops/ms | |
[info] EffFlattenBenchmark.benchEffFlatten_Builder 50 thrpt 5 2907.176 ± 26.562 ops/ms | |
[info] EffFlattenBenchmark.benchEffFlatten_Builder 100 thrpt 5 1553.765 ± 33.479 ops/ms | |
[info] EffFlattenBenchmark.benchEffFlatten_Builder 500 thrpt 5 297.438 ± 9.401 ops/ms | |
[info] EffFlattenBenchmark.benchEffFlatten_Collect 50 thrpt 5 4899.624 ± 126.770 ops/ms | |
[info] EffFlattenBenchmark.benchEffFlatten_Collect 100 thrpt 5 2630.149 ± 35.264 ops/ms | |
[info] EffFlattenBenchmark.benchEffFlatten_Collect 500 thrpt 5 511.721 ± 8.355 ops/ms | |
[info] EffFlattenBenchmark.benchEffFlatten_FoldLeftBuilder 50 thrpt 5 2817.795 ± 79.083 ops/ms | |
[info] EffFlattenBenchmark.benchEffFlatten_FoldLeftBuilder 100 thrpt 5 1437.505 ± 33.103 ops/ms | |
[info] EffFlattenBenchmark.benchEffFlatten_FoldLeftBuilder 500 thrpt 5 285.858 ± 9.366 ops/ms | |
[info] EffFlattenBenchmark.benchEffFlatten_FoldLeftList 50 thrpt 5 4281.285 ± 97.378 ops/ms | |
[info] EffFlattenBenchmark.benchEffFlatten_FoldLeftList 100 thrpt 5 2303.624 ± 36.768 ops/ms | |
[info] EffFlattenBenchmark.benchEffFlatten_FoldLeftList 500 thrpt 5 320.638 ± 2.261 ops/ms | |
[info] EffFlattenBenchmark.benchEffFlatten_FoldRightList 50 thrpt 5 2894.644 ± 79.858 ops/ms | |
[info] EffFlattenBenchmark.benchEffFlatten_FoldRightList 100 thrpt 5 1450.015 ± 45.743 ops/ms | |
[info] EffFlattenBenchmark.benchEffFlatten_FoldRightList 500 thrpt 5 274.268 ± 8.043 ops/ms | |
[info] EffFlattenBenchmark.benchEffFlatten_NoReverse 50 thrpt 5 4503.200 ± 88.736 ops/ms | |
[info] EffFlattenBenchmark.benchEffFlatten_NoReverse 100 thrpt 5 2356.487 ± 80.884 ops/ms | |
[info] EffFlattenBenchmark.benchEffFlatten_NoReverse 500 thrpt 5 462.636 ± 7.592 ops/ms | |
[info] EffFlattenBenchmark.benchEffFlatten_Raw 50 thrpt 5 2987.859 ± 76.475 ops/ms | |
[info] EffFlattenBenchmark.benchEffFlatten_Raw 100 thrpt 5 1350.700 ± 27.003 ops/ms | |
[info] EffFlattenBenchmark.benchEffFlatten_Raw 500 thrpt 5 309.497 ± 7.093 ops/ms | |
*/ | |
@State(Scope.Thread) | |
@BenchmarkMode(Array(Mode.Throughput)) | |
@OutputTimeUnit(TimeUnit.MILLISECONDS) | |
@Warmup(iterations = 5, time = 1, timeUnit = TimeUnit.SECONDS) | |
@Measurement(iterations = 5, time = 1, timeUnit = TimeUnit.SECONDS) | |
@Fork(1) | |
class EffFlattenBenchmark { | |
var list: List[Option[Int]] = _ | |
@Param(Array("50", "100", "500")) | |
var size: Int = _ | |
@Setup(Level.Trial) | |
def setup(): Unit = | |
list = (1 to size) | |
.map(_ => { | |
val r = Random.nextInt() | |
if (r % 3 == 0) None else Some(r) | |
}) | |
.toList | |
@tailrec | |
final def effFlatten[T](l: List[Option[T]], acc: List[T]): List[T] = | |
l match { | |
case Nil => acc.reverse // а нужен ли reverse() ? | |
case Some(h) :: tail => effFlatten(tail, h :: acc) | |
case None :: tail => effFlatten(tail, acc) | |
} | |
final def effFlatten[T](l: List[Option[T]]): List[T] = { | |
@tailrec | |
def goFlatten(l: List[Option[T]], acc: List[T]): List[T] = | |
l match { | |
case Nil => acc.reverse // а нужен ли reverse() ? | |
case Some(h) :: tail => goFlatten(tail, h :: acc) | |
case None :: tail => goFlatten(tail, acc) | |
} | |
goFlatten(l, Nil) | |
} | |
final def effFlattenNoReverse[T](l: List[Option[T]]): List[T] = { | |
@tailrec | |
def goFlatten(l: List[Option[T]], acc: List[T]): List[T] = | |
l match { | |
case Nil => acc | |
case Some(h) :: tail => goFlatten(tail, h :: acc) | |
case None :: tail => goFlatten(tail, acc) | |
} | |
goFlatten(l, Nil) | |
} | |
final def effFlattenFoldRightList[T](l: List[Option[T]]): List[T] = | |
l.foldRight(Nil: List[T])((a, acc) => a.fold(acc)(_ :: acc)) | |
final def effFlattenFoldLeftList[T](l: List[Option[T]]): List[T] = | |
l.foldLeft(Nil: List[T])((acc, a) => a.fold(acc)(_ :: acc)) | |
final def effFlattenFoldLeftBuilder[T](l: List[Option[T]]): List[T] = | |
l.foldLeft(List.newBuilder[T])((acc, a) => a.fold(acc)(acc.addOne)).result() | |
final def effFlattenCollect[T](l: List[Option[T]]): List[T] = | |
l.collect { case Some(a) => a } | |
final def effFlattenBuilder[T](l: List[Option[T]]): List[T] = { | |
val builder = List.newBuilder[T] | |
l.foreach(_.foreach(builder.addOne)) | |
builder.result() | |
} | |
@Benchmark def benchEffFlatten_Raw: List[Int] = effFlatten[Int](list, Nil) | |
@Benchmark def benchEffFlatten_FoldLeftBuilder: List[Int] = effFlattenFoldLeftBuilder[Int](list) | |
@Benchmark def benchEffFlatten_Builder: List[Int] = effFlattenBuilder[Int](list) | |
@Benchmark def benchEffFlatten_Collect: List[Int] = effFlattenCollect[Int](list) | |
@Benchmark def benchEffFlatten: List[Int] = effFlatten[Int](list) | |
@Benchmark def benchEffFlatten_NoReverse: List[Int] = effFlattenNoReverse[Int](list) | |
@Benchmark def benchEffFlatten_FoldRightList: List[Int] = effFlattenFoldRightList[Int](list) | |
@Benchmark def benchEffFlatten_FoldLeftList: List[Int] = effFlattenFoldLeftList[Int](list) | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment