import org.openjdk.jmh.annotations.{Benchmark, BenchmarkMode, Fork, Measurement, Mode, Param, Scope, State, Warmup}
import java.util.ArrayDeque
import scala.util.Random
import org.openjdk.jmh.annotations.Setup
import scala.jdk.StreamConverters.*
case class Cls(i: Int)
@BenchmarkMode(Array(Mode.Throughput))
@State(Scope.Benchmark)
@Measurement(time = 1, iterations = 5)
@Warmup(time = 1, iterations = 5)
@Fork(value = 2)
class Bench:
@Param(Array("100", "10000", "100000", "1000000"))
var size: Int = _
var data: Array[Cls] = _
var list: List[Cls] = _
var vector: Vector[Cls] = _
@Setup
def setup(): Unit =
data = Array.fill(size)(Cls(Random.nextInt))
list = List.from(data)
vector = Vector.from(data)
@Benchmark
def listBuilderAndSum: Long =
val builder = List.newBuilder[Cls]
for cls <- data do builder.addOne(cls)
val list = builder.result()
list.filter(_.i > 0).map(_.i.toLong).sum
@Benchmark
def vectorBuilderAndSum: Long =
val builder = Vector.newBuilder[Cls]
for i <- data do builder.addOne(i)
val vec = builder.result
vec.filter(_.i > 0).map(_.i.toLong).sum
@Benchmark
def vectorBuildDirectAndSum: Long =
var vec = Vector.empty[Cls]
for cls <- data do vec = vec :+ cls
vec.filter(_.i > 0).map(_.i.toLong).sum
@Benchmark
def listPrependAndSum: Long =
var lst = List.empty[Cls]
for cls <- data do lst = cls :: lst
lst.filter(_.i > 0).map(_.i.toLong).sum
@Benchmark
def vectorPrependAndSum: Long =
var vec = Vector.empty[Cls]
for cls <- data do vec = cls +: vec
vec.filter(_.i > 0).map(_.i.toLong).sum
@Benchmark
def listSum: Long =
list.filter(_.i > 0).map(_.i.toLong).sum
@Benchmark
def vectorSum: Long =
vector.filter(_.i > 0).map(_.i.toLong).sum
@Benchmark
def listViewSum: Long =
list.view.filter(_.i > 0).map(_.i.toLong).sum
@Benchmark
def vectorViewSum: Long =
vector.view.filter(_.i > 0).map(_.i.toLong).sum
@Benchmark
def listJavaStreamSum: Long =
list.asJavaSeqStream.filter(_.i > 0).mapToLong(_.i.toLong).sum
@Benchmark
def vectorJavaStreamSum: Long =
vector.asJavaSeqStream.filter(_.i > 0).mapToLong(_.i.toLong).sum