Skip to content

Commit

Permalink
More chain benchmarks
Browse files Browse the repository at this point in the history
  • Loading branch information
Luka Jacobowitz committed Aug 9, 2018
1 parent 2854651 commit 8e7b9e8
Show file tree
Hide file tree
Showing 3 changed files with 25 additions and 5 deletions.
21 changes: 18 additions & 3 deletions bench/src/main/scala/cats/bench/CatenableBench.scala
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package cats.bench

import cats.data.Catenable
import chain.Chain
import org.openjdk.jmh.annotations.{Benchmark, Scope, State}

@State(Scope.Thread)
Expand All @@ -9,40 +10,54 @@ class CatenableBench {
private val smallCatenable = Catenable(1, 2, 3, 4, 5)
private val smallVector = Vector(1, 2, 3, 4, 5)
private val smallList = List(1, 2, 3, 4, 5)
private val smallChain = Chain(smallList)

private val largeCatenable = Catenable.fromSeq(0 to 1000000)
private val largeVector = (0 to 1000000).toVector
private val largeList = (0 to 1000000).toList
private val largeChain = (0 to 1000).foldLeft(Chain.empty[Int])((acc, _) => acc ++ Chain(0 to 1000))

private val largeNestedCatenable = largeList.map(Catenable.singleton)
private val largeNestedVector = largeList.map(Vector(_))
private val largeNestedList = largeList.map(List(_))

@Benchmark def mapSmallCatenable: Catenable[Int] = smallCatenable.map(_ + 1)
@Benchmark def mapSmallVector: Vector[Int] = smallVector.map(_ + 1)
@Benchmark def mapSmallList: List[Int] = smallList.map(_ + 1)
@Benchmark def mapSmallChain: Chain[Int] = smallChain.map(_ + 1)

@Benchmark def mapLargeCatenable: Catenable[Int] = largeCatenable.map(_ + 1)
@Benchmark def mapLargeVector: Vector[Int] = largeVector.map(_ + 1)
@Benchmark def mapLargeList: List[Int] = largeList.map(_ + 1)
@Benchmark def mapLargeChain: Chain[Int] = largeChain.map(_ + 1)


@Benchmark def foldLeftSmallCatenable: Int = smallCatenable.foldLeft(0)(_ + _)
@Benchmark def foldLeftSmallVector: Int = smallVector.foldLeft(0)(_ + _)
@Benchmark def foldLeftSmallList: Int = smallList.foldLeft(0)(_ + _)
@Benchmark def foldLeftSmallChain: Int = smallChain.foldLeft(0)(_ + _)

@Benchmark def foldLeftLargeCatenable: Int = largeCatenable.foldLeft(0)(_ + _)
@Benchmark def foldLeftLargeVector: Int = largeVector.foldLeft(0)(_ + _)
@Benchmark def foldLeftLargeList: Int = largeList.foldLeft(0)(_ + _)
@Benchmark def foldLeftLargeChain: Int = largeChain.foldLeft(0)(_ + _)


@Benchmark def consSmallCatenable: Catenable[Int] = 0 +: smallCatenable
@Benchmark def consSmallVector: Vector[Int] = 0 +: smallVector
@Benchmark def consSmallList: List[Int] = 0 +: smallList
@Benchmark def consSmallChain: Chain[Int] = 0 +: smallChain

@Benchmark def consLargeCatenable: Catenable[Int] = 0 +: largeCatenable
@Benchmark def consLargeVector: Vector[Int] = 0 +: largeVector
@Benchmark def consLargeList: List[Int] = 0 +: largeList
@Benchmark def consLargeChain: Chain[Int] = 0 +: largeChain


@Benchmark def createTinyCatenable: Catenable[Int] = Catenable(1)
@Benchmark def createTinyVector: Vector[Int] = Vector(1)
@Benchmark def createTinyList: List[Int] = List(1)
@Benchmark def createTinyChain: Chain[Int] = Chain.single(1)

@Benchmark def createSmallCatenable: Catenable[Int] = Catenable(1, 2, 3, 4, 5)
@Benchmark def createSmallVector: Vector[Int] = Vector(1, 2, 3, 4, 5)
@Benchmark def createSmallList: List[Int] = List(1, 2, 3, 4, 5)
@Benchmark def createSmallChain: Chain[Int] = Chain(Seq(1, 2, 3, 4, 5))
}
5 changes: 5 additions & 0 deletions core/src/main/scala/cats/data/Catenable.scala
Original file line number Diff line number Diff line change
Expand Up @@ -249,6 +249,9 @@ object Catenable extends CatenableInstances {
/** Creates a catenable of 1 element. */
def singleton[A](a: A): Catenable[A] = Singleton(a)

/** Alias for singleton */
def one[A](a: A): Catenable[A] = singleton(a)

/** Appends two catenables. */
def append[A](c: Catenable[A], c2: Catenable[A]): Catenable[A] =
if (c.isEmpty) c2
Expand Down Expand Up @@ -279,6 +282,7 @@ object Catenable extends CatenableInstances {
case _ => fromSeq(as)
}

// scalastyle:off null
class CatenableIterator[A](self: Catenable[A]) extends Iterator[A] {
var c: Catenable[A] = if (self.isEmpty) null else self
val rights = new collection.mutable.ArrayBuffer[Catenable[A]]
Expand All @@ -303,6 +307,7 @@ object Catenable extends CatenableInstances {
go
}
}
// scalastyle:on null
}

private[data] sealed abstract class CatenableInstances {
Expand Down
4 changes: 2 additions & 2 deletions laws/src/main/scala/cats/laws/discipline/Arbitrary.scala
Original file line number Diff line number Diff line change
Expand Up @@ -279,9 +279,9 @@ object arbitrary extends ArbitraryInstances0 {
implicit def catsLawsArbitraryForCatenable[A](implicit A: Arbitrary[A]): Arbitrary[Catenable[A]] =
Arbitrary(Gen.sized {
case 0 => Gen.const(Catenable.nil)
case 1 => A.arbitrary.map(Catenable.singleton)
case 1 => A.arbitrary.map(Catenable.one)
case 2 => A.arbitrary.flatMap(a1 => A.arbitrary.flatMap(a2 =>
Catenable.append(Catenable.singleton(a1), Catenable.singleton(a2))))
Catenable.append(Catenable.one(a1), Catenable.one(a2))))
case n => Catenable.fromSeq(Range.apply(0, n)).foldLeft(Gen.const(Catenable.empty[A])) { (gen, _) =>
gen.flatMap(cat => A.arbitrary.map(a => cat :+ a))
}
Expand Down

0 comments on commit 8e7b9e8

Please sign in to comment.