Created
February 25, 2026 16:18
-
-
Save bishabosha/4f373929fc7a8d8f96824dfc3ffac98c to your computer and use it in GitHub Desktop.
NamedTuple toSeqMap benchmark
This file contains hidden or 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
| //> using scala "3.8.2" | |
| //> using jmh | |
| // run with `scala --power bench.scala` | |
| package bench | |
| import org.openjdk.jmh.annotations.Benchmark | |
| import org.openjdk.jmh.annotations.BenchmarkMode | |
| import org.openjdk.jmh.annotations.Level | |
| 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.infra.Blackhole | |
| import java.util.concurrent.TimeUnit | |
| import scala.collection.immutable.ListMap | |
| import scala.collection.immutable.SeqMap | |
| import scala.compiletime.uninitialized | |
| import scala.util.Random | |
| @BenchmarkMode(Array(Mode.AverageTime)) | |
| @OutputTimeUnit(TimeUnit.NANOSECONDS) | |
| class NamedTupleToSeqMap_SeqMapVsListMap_Benchmark { | |
| import NamedTupleToSeqMap_SeqMapVsListMap_Benchmark.BenchmarkState | |
| @Benchmark | |
| def seqMap_newBuilder_addAll(state: BenchmarkState, blackhole: Blackhole): Unit = | |
| val map = (SeqMap.newBuilder[String, Any] ++= state.mkEntries()).result() | |
| blackhole.consume(map) | |
| @Benchmark | |
| def listMap_newBuilder_addAll(state: BenchmarkState, blackhole: Blackhole): Unit = | |
| val map = (ListMap.newBuilder[String, Any] ++= state.mkEntries()).result() | |
| blackhole.consume(map) | |
| @Benchmark | |
| def seqMap_apply_1000_keys(state: BenchmarkState, blackhole: Blackhole): Unit = | |
| val keys = state.randomAccessKeys | |
| val keyLength = keys.length | |
| val map = state.seqMap | |
| var i = 0 | |
| while i < keyLength do | |
| blackhole.consume(map(keys(i))) | |
| i += 1 | |
| @Benchmark | |
| def listMap_apply_1000_keys(state: BenchmarkState, blackhole: Blackhole): Unit = | |
| val keys = state.randomAccessKeys | |
| val keyLength = keys.length | |
| val map = state.listMap | |
| var i = 0 | |
| while i < keyLength do | |
| blackhole.consume(map(keys(i))) | |
| i += 1 | |
| } | |
| object NamedTupleToSeqMap_SeqMapVsListMap_Benchmark { | |
| @State(Scope.Thread) | |
| class BenchmarkState { | |
| @Param(Array("1", "2", "3", "4", "5", "10", "25", "100")) | |
| var size: Int = 0 | |
| var mkEntries: () => Iterator[(String, Any)] = uninitialized | |
| var seqMap: SeqMap[String, Any] = uninitialized | |
| var listMap: ListMap[String, Any] = uninitialized | |
| var randomAccessKeys: Array[String] = uninitialized | |
| @Setup | |
| def setup(): Unit = { | |
| def singleCharKey(i: Int) = String.valueOf((0x0100 + i).toChar) | |
| object obj | |
| val rng = new Random(0xC0FFEE + size) | |
| val sampledKeys = rng | |
| .shuffle((0 until 4096).toVector) | |
| .take(size) | |
| .map(singleCharKey) | |
| val entries = sampledKeys.map(k => k -> obj) | |
| val (names, values) = | |
| val (names0, values0) = entries.toArray.unzip | |
| Tuple.fromArray(names0) -> Tuple.fromArray(values0) | |
| // simulate making iterators from tuple of names and tuple of values | |
| mkEntries = () => names.productIterator.asInstanceOf[Iterator[String]].zip(values.productIterator) | |
| seqMap = SeqMap.from(entries) | |
| listMap = ListMap.from(entries) | |
| val accessCount = 1_000 | |
| randomAccessKeys = Array.tabulate(accessCount): _ => | |
| sampledKeys(rng.nextInt(size)) | |
| } | |
| } | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment