Skip to content

Instantly share code, notes, and snippets.

@bishabosha
Created February 25, 2026 16:18
Show Gist options
  • Select an option

  • Save bishabosha/4f373929fc7a8d8f96824dfc3ffac98c to your computer and use it in GitHub Desktop.

Select an option

Save bishabosha/4f373929fc7a8d8f96824dfc3ffac98c to your computer and use it in GitHub Desktop.
NamedTuple toSeqMap benchmark
//> 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