Skip to content

Commit 21aa369

Browse files
author
Luka Jacobowitz
authored
Add Chain (typelevel#2371)
* Add Catenable * Add law tests and simple arbitrary and eq instances * More tests * Add benchmarks * Add chain benchmarks * Add Iterator * More chain benchmarks * Add Paul and Pavel to Authors and change COPYING to Cats Contributors * More Tests * Add reverse, groupBy and zipWith * Add Collection Wrapping optimization * Add traverse and foldRight implementations that don't convert to List * Rename to Chain; add reverseIterator * More efficient implementations * Use Vector for reversing * Remove redundant benchmarking methods * Format scaladoc consistently * Rename snoc and cons to append and prepend for consistency * Add proper Eq, PartialOrder, Order and Coflatmap instances
1 parent fc21141 commit 21aa369

File tree

8 files changed

+889
-2
lines changed

8 files changed

+889
-2
lines changed

AUTHORS.md

+2
Original file line numberDiff line numberDiff line change
@@ -149,8 +149,10 @@ possible:
149149
* P. Oscar Boykin
150150
* Paolo G. Giarrusso
151151
* Pascal Voitot
152+
* Paul Chiusano
152153
* Paul Phillips
153154
* Paulo "JCranky" Siqueira
155+
* Pavel Chlupacek
154156
* Pavkin Vladimir
155157
* Pepe García
156158
* Pere Villega

COPYING

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
Cats Copyright (c) 2015 Erik Osheim.
1+
Cats Copyright (c) 2015 Cats Contributors.
22

33
Permission is hereby granted, free of charge, to any person obtaining a copy of
44
this software and associated documentation files (the "Software"), to deal in
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
package cats.bench
2+
3+
import cats.data.Chain
4+
import fs2.Catenable
5+
import chain.{Chain => OldChain}
6+
import org.openjdk.jmh.annotations.{Benchmark, Scope, State}
7+
8+
@State(Scope.Thread)
9+
class ChainBench {
10+
11+
private val smallChain = Chain(1, 2, 3, 4, 5)
12+
private val smallCatenable = Catenable(1, 2, 3, 4, 5)
13+
private val smallVector = Vector(1, 2, 3, 4, 5)
14+
private val smallList = List(1, 2, 3, 4, 5)
15+
private val smallOldChain = OldChain(smallList)
16+
17+
private val largeChain = (0 to 1000)
18+
.foldLeft(Chain.empty[Int])((acc, _) => acc ++ Chain.fromSeq(0 to 1000))
19+
private val largeCatenable = Catenable.fromSeq(0 to 1000000)
20+
private val largeVector = (0 to 1000000).toVector
21+
private val largeList = (0 to 1000000).toList
22+
private val largeOldChain = (0 to 1000).foldLeft(OldChain.empty[Int])((acc, _) => acc ++ OldChain(0 to 1000))
23+
24+
25+
@Benchmark def mapSmallChain: Chain[Int] = smallChain.map(_ + 1)
26+
@Benchmark def mapSmallCatenable: Catenable[Int] = smallCatenable.map(_ + 1)
27+
@Benchmark def mapSmallVector: Vector[Int] = smallVector.map(_ + 1)
28+
@Benchmark def mapSmallList: List[Int] = smallList.map(_ + 1)
29+
@Benchmark def mapSmallOldChain: OldChain[Int] = smallOldChain.map(_ + 1)
30+
31+
32+
@Benchmark def mapLargeChain: Chain[Int] = largeChain.map(_ + 1)
33+
@Benchmark def mapLargeCatenable: Catenable[Int] = largeCatenable.map(_ + 1)
34+
@Benchmark def mapLargeVector: Vector[Int] = largeVector.map(_ + 1)
35+
@Benchmark def mapLargeList: List[Int] = largeList.map(_ + 1)
36+
@Benchmark def mapLargeOldChain: OldChain[Int] = largeOldChain.map(_ + 1)
37+
38+
39+
40+
@Benchmark def foldLeftSmallChain: Int = smallChain.foldLeft(0)(_ + _)
41+
@Benchmark def foldLeftSmallCatenable: Int = smallCatenable.foldLeft(0)(_ + _)
42+
@Benchmark def foldLeftSmallVector: Int = smallVector.foldLeft(0)(_ + _)
43+
@Benchmark def foldLeftSmallList: Int = smallList.foldLeft(0)(_ + _)
44+
@Benchmark def foldLeftSmallOldChain: Int = smallOldChain.foldLeft(0)(_ + _)
45+
46+
47+
@Benchmark def foldLeftLargeChain: Int = largeChain.foldLeft(0)(_ + _)
48+
@Benchmark def foldLeftLargeCatenable: Int = largeCatenable.foldLeft(0)(_ + _)
49+
@Benchmark def foldLeftLargeVector: Int = largeVector.foldLeft(0)(_ + _)
50+
@Benchmark def foldLeftLargeList: Int = largeList.foldLeft(0)(_ + _)
51+
@Benchmark def foldLeftLargeOldChain: Int = largeOldChain.foldLeft(0)(_ + _)
52+
53+
54+
55+
56+
@Benchmark def consSmallChain: Chain[Int] = 0 +: smallChain
57+
@Benchmark def consSmallCatenable: Catenable[Int] = 0 +: smallCatenable
58+
@Benchmark def consSmallVector: Vector[Int] = 0 +: smallVector
59+
@Benchmark def consSmallList: List[Int] = 0 +: smallList
60+
@Benchmark def consSmallOldChain: OldChain[Int] = 0 +: smallOldChain
61+
62+
@Benchmark def consLargeChain: Chain[Int] = 0 +: largeChain
63+
@Benchmark def consLargeCatenable: Catenable[Int] = 0 +: largeCatenable
64+
@Benchmark def consLargeVector: Vector[Int] = 0 +: largeVector
65+
@Benchmark def consLargeList: List[Int] = 0 +: largeList
66+
@Benchmark def consLargeOldChain: OldChain[Int] = 0 +: largeOldChain
67+
68+
@Benchmark def createTinyChain: Chain[Int] = Chain(1)
69+
@Benchmark def createTinyCatenable: Catenable[Int] = Catenable(1)
70+
@Benchmark def createTinyVector: Vector[Int] = Vector(1)
71+
@Benchmark def createTinyList: List[Int] = List(1)
72+
@Benchmark def createTinyOldChain: OldChain[Int] = OldChain.single(1)
73+
74+
@Benchmark def createSmallChain: Chain[Int] = Chain(1, 2, 3, 4, 5)
75+
@Benchmark def createSmallCatenable: Catenable[Int] = Catenable(1, 2, 3, 4, 5)
76+
@Benchmark def createSmallVector: Vector[Int] = Vector(1, 2, 3, 4, 5)
77+
@Benchmark def createSmallList: List[Int] = List(1, 2, 3, 4, 5)
78+
@Benchmark def createSmallOldChain: OldChain[Int] = OldChain(Seq(1, 2, 3, 4, 5))
79+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
package cats.bench
2+
3+
import cats.Monoid
4+
import cats.data.Chain
5+
import cats.implicits._
6+
import chain.{Chain => OldChain}
7+
import org.openjdk.jmh.annotations.{Benchmark, Scope, State}
8+
9+
@State(Scope.Thread)
10+
class CollectionMonoidBench {
11+
12+
private val largeList = (0 to 1000000).toList
13+
14+
implicit def monoidOldChain[A]: Monoid[OldChain[A]] = new Monoid[OldChain[A]] {
15+
def empty: OldChain[A] = OldChain.empty[A]
16+
17+
def combine(x: OldChain[A], y: OldChain[A]): OldChain[A] = x ++ y
18+
}
19+
20+
@Benchmark def accumulateChain: Chain[Int] = largeList.foldMap(Chain.one)
21+
@Benchmark def accumulateVector: Vector[Int] = largeList.foldMap(Vector(_))
22+
@Benchmark def accumulateList: List[Int] = largeList.foldMap(List(_))
23+
@Benchmark def accumulateOldChain: OldChain[Int] = largeList.foldMap(OldChain.single)
24+
}

build.sbt

+4-1
Original file line numberDiff line numberDiff line change
@@ -491,7 +491,10 @@ lazy val bench = project.dependsOn(macrosJVM, coreJVM, freeJVM, lawsJVM)
491491
.settings(commonJvmSettings)
492492
.settings(coverageEnabled := false)
493493
.settings(libraryDependencies ++= Seq(
494-
"org.scalaz" %% "scalaz-core" % "7.2.23"))
494+
"org.scalaz" %% "scalaz-core" % "7.2.23",
495+
"org.spire-math" %% "chain" % "0.3.0",
496+
"co.fs2" %% "fs2-core" % "0.10.4"
497+
))
495498
.enablePlugins(JmhPlugin)
496499

497500
// cats-js is JS-only

0 commit comments

Comments
 (0)