Skip to content

Instantly share code, notes, and snippets.

@joshlemer
Created January 4, 2020 16:31
Show Gist options
  • Save joshlemer/9839b185a088dbce7285a163ec0d70ce to your computer and use it in GitHub Desktop.
Save joshlemer/9839b185a088dbce7285a163ec0d70ce to your computer and use it in GitHub Desktop.
List opt -- from vs prependedAll
// class List
override def prependedAll[B >: A](prefix: collection.IterableOnce[B]): List[B] = prefix match {
case xs: List[B] => xs ::: this
case _ =>
val iter = prefix.iterator
if (iter.hasNext) {
val result = new ::[B](iter.next(), null)
var curr = result
while (iter.hasNext) {
val temp = new ::[B](iter.next(), null)
curr.next = temp
curr = temp
}
curr.next = this
releaseFence()
result
} else {
this
}
}
// object List
def fromStefan[B](coll: collection.IterableOnce[B]): List[B] = coll match {
case coll: List[B] => coll
case _ if coll.knownSize == 0 => empty[B]
case b: ListBuffer[B] => b.toList
case _ => Nil.prependedAll(coll)
}
def from[B](coll: collection.IterableOnce[B]): List[B] = coll match {
case coll: List[B] => coll
case _ if coll.knownSize == 0 => empty[B]
case b: ListBuffer[B] => b.toList
case _ =>
val iter = coll.iterator
if (iter.hasNext) {
val head = new ::[B](iter.next(), Nil)
var curr = head
while (iter.hasNext) {
val temp = new ::[B](iter.next(), Nil)
curr.next = temp
curr = temp
}
releaseFence()
head
} else {
Nil
}
}
package scala.collection.immutable
import java.util.concurrent.TimeUnit
import org.openjdk.jmh.annotations._
import org.openjdk.jmh.infra.Blackhole
object ListBenchmark {
case class Content(value: Int)
}
@BenchmarkMode(Array(Mode.AverageTime))
@Fork(2)
@Threads(1)
@Warmup(iterations = 20)
@Measurement(iterations = 20)
@OutputTimeUnit(TimeUnit.NANOSECONDS)
@State(Scope.Benchmark)
class ListBenchmark {
@Param(Array("0", "1", "10", "50", "100", "1000", "10000"))
var size: Int = _
var prefix: List[Int] = Nil
var prefixVector: Vector[Int] = Vector()
var suffix: List[Int] = Nil
@Setup(Level.Trial) def initKeys(): Unit = {
prefix = List.fill(size)(0)
prefixVector = Vector.fill(size)(0)
suffix = List.fill(size)(0)
}
@Benchmark def fromVectorJosh(bh: Blackhole): Unit = {
bh.consume(List.from(prefixVector))
}
@Benchmark def fromVectorStef(bh: Blackhole): Unit = {
bh.consume(List.fromStefan(prefixVector))
}
}
[info] Benchmark (size) Mode Cnt Score Error Units
[info] ListBenchmark.fromVectorJosh 0 avgt 40 3.013 ± 0.854 ns/op
[info] ListBenchmark.fromVectorJosh 1 avgt 40 15.548 ± 1.263 ns/op
[info] ListBenchmark.fromVectorJosh 10 avgt 40 57.049 ± 4.351 ns/op
[info] ListBenchmark.fromVectorJosh 50 avgt 40 213.084 ± 16.275 ns/op
[info] ListBenchmark.fromVectorJosh 100 avgt 40 414.603 ± 10.533 ns/op
[info] ListBenchmark.fromVectorJosh 1000 avgt 40 4171.134 ± 195.551 ns/op
[info] ListBenchmark.fromVectorJosh 10000 avgt 40 42188.129 ± 842.183 ns/op
[info] ListBenchmark.fromVectorStef 0 avgt 40 2.603 ± 0.066 ns/op
[info] ListBenchmark.fromVectorStef 1 avgt 40 16.772 ± 0.540 ns/op
[info] ListBenchmark.fromVectorStef 10 avgt 40 60.963 ± 5.302 ns/op
[info] ListBenchmark.fromVectorStef 50 avgt 40 235.702 ± 12.331 ns/op
[info] ListBenchmark.fromVectorStef 100 avgt 40 429.090 ± 9.116 ns/op
[info] ListBenchmark.fromVectorStef 1000 avgt 40 4175.865 ± 66.990 ns/op
[info] ListBenchmark.fromVectorStef 10000 avgt 40 42983.755 ± 2003.122 ns/op
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment