Skip to content

Commit fd8a54a

Browse files
authored
Merge pull request #70 from szeiger/wip/new-stepper-materialization
A new approach to Stepper and Stream materialization
2 parents 466e8d4 + 1590004 commit fd8a54a

26 files changed

+518
-745
lines changed

benchmark/README.md

+5-9
Original file line numberDiff line numberDiff line change
@@ -14,18 +14,14 @@ Because the benchmarking is **very computationally expensive** it should be done
1414

1515
1. Make sure your terminal has plenty of lines of scrollback. (A couple thousand should do.)
1616

17-
2. Run `sbt`
17+
2. Run `sbt "jmh:run -i 5 -wi 3 -f 5"`. Wait overnight.
1818

19-
3. Enter `jmh:run -i 5 -wi 3 -f5`. Wait overnight.
19+
3. Clip off the last set of lines from the terminal window starting before the line that contains `[info] # Run complete. Total time:` and including that line until the end.
2020

21-
4. Clip off the last set of lines from the terminal window starting before the line that contains `[info] # Run complete. Total time:` and including that line until the end.
22-
23-
5. Save that in the file `results/jmhbench.log`
21+
4. Save that in the file `results/jmhbench.log`
2422

2523
## Comparison step
2624

27-
1. Run `sbt console`
28-
29-
2. Enter `bench.examine.SpeedReports()`
25+
1. Run `sbt parseJmh`
3026

31-
3. Look at the ASCII art results showing speed comparisons.
27+
2. Look at the ASCII art results showing speed comparisons.

benchmark/build.sbt

+3-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
enablePlugins(JmhPlugin)
22

33
val generateJmh = TaskKey[Unit]("generateJmh", "Generates JMH benchmark sources.")
4+
val parseJmh = TaskKey[Unit]("parseJmh", "Parses JMH benchmark logs in results/jmhbench.log.")
45

56
lazy val root = (project in file(".")).settings(
67
name := "java8-compat-bench",
@@ -11,5 +12,6 @@ lazy val root = (project in file(".")).settings(
1112
unmanagedJars in Compile ++= Seq(baseDirectory.value / "../target/scala-2.11/scala-java8-compat_2.11-0.8.0-SNAPSHOT.jar"),
1213
// This would be nicer but sbt-jmh doesn't like it:
1314
//unmanagedClasspath in Compile += Attributed.blank(baseDirectory.value / "../target/scala-2.11/classes"),
14-
generateJmh := (runMain in Compile).toTask(" bench.codegen.GenJmhBench").value
15+
generateJmh := (runMain in Compile).toTask(" bench.codegen.GenJmhBench").value,
16+
parseJmh := (runMain in Compile).toTask(" bench.examine.ParseJmhLog").value
1517
)

benchmark/src/main/scala/bench/CollectionSource.scala

+29-28
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import scala.collection.generic.CanBuildFrom
66
import scala.compat.java8.StreamConverters._
77
import scala.compat.java8.collectionImpl._
88
import scala.compat.java8.converterImpl._
9+
import scala.compat.java8.{MakesSequentialStream, MakesParallelStream}
910

1011
package object generate {
1112
private def myInty(n: Int) = 0 until n
@@ -25,42 +26,42 @@ package object generate {
2526
}
2627

2728
object Pstep {
28-
def i[CC](cc: CC)(implicit steppize: CC => MakesStepper[IntStepper with EfficientSubstep]): IntStepper =
29+
def i[CC](cc: CC)(implicit steppize: CC => MakesStepper[Int, EfficientSubstep]): IntStepper =
2930
steppize(cc).stepper
30-
def s[CC](cc: CC)(implicit steppize: CC => MakesStepper[AnyStepper[String] with EfficientSubstep]): AnyStepper[String] =
31+
def s[CC](cc: CC)(implicit steppize: CC => MakesStepper[String, EfficientSubstep]): AnyStepper[String] =
3132
steppize(cc).stepper
3233
}
3334

3435
object Sstep {
35-
def i[CC](cc: CC)(implicit steppize: CC => MakesStepper[IntStepper]): IntStepper =
36+
def i[CC](cc: CC)(implicit steppize: CC => MakesStepper[Int, Any]): IntStepper =
3637
steppize(cc).stepper
37-
def s[CC](cc: CC)(implicit steppize: CC => MakesStepper[AnyStepper[String]]): AnyStepper[String] =
38+
def s[CC](cc: CC)(implicit steppize: CC => MakesStepper[String, Any]): AnyStepper[String] =
3839
steppize(cc).stepper
3940
}
4041

4142
object PsStream {
42-
def i[CC](cc: CC)(implicit steppize: CC => MakesStepper[IntStepper with EfficientSubstep]): IntStream =
43+
def i[CC](cc: CC)(implicit steppize: CC => MakesStepper[Int, EfficientSubstep]): IntStream =
4344
steppize(cc).stepper.parStream
44-
def s[CC](cc: CC)(implicit steppize: CC => MakesStepper[AnyStepper[String] with EfficientSubstep]): Stream[String] =
45+
def s[CC](cc: CC)(implicit steppize: CC => MakesStepper[String, EfficientSubstep]): Stream[String] =
4546
steppize(cc).stepper.parStream
4647
}
4748

4849
object SsStream {
49-
def i[CC](cc: CC)(implicit steppize: CC => MakesStepper[IntStepper]): IntStream =
50+
def i[CC](cc: CC)(implicit steppize: CC => MakesStepper[Int, Any]): IntStream =
5051
steppize(cc).stepper.seqStream
51-
def s[CC](cc: CC)(implicit steppize: CC => MakesStepper[AnyStepper[String]]): Stream[String] =
52+
def s[CC](cc: CC)(implicit steppize: CC => MakesStepper[String, Any]): Stream[String] =
5253
steppize(cc).stepper.seqStream
5354
}
5455

5556
object Sstream {
56-
def i[CC](cc: CC)(implicit streamize: CC => MakesSequentialStream[java.lang.Integer, IntStream]) =
57+
def i[CC](cc: CC)(implicit streamize: CC => MakesSequentialStream[Int, IntStream]) =
5758
streamize(cc).seqStream
5859
def s[CC](cc: CC)(implicit streamize: CC => MakesSequentialStream[String, Stream[String]]) =
5960
streamize(cc).seqStream
6061
}
6162

6263
object Pstream {
63-
def i[CC](cc: CC)(implicit streamize: CC => MakesParallelStream[java.lang.Integer, IntStream]) =
64+
def i[CC](cc: CC)(implicit streamize: CC => MakesParallelStream[Int, IntStream]) =
6465
streamize(cc).parStream
6566
def s[CC](cc: CC)(implicit streamize: CC => MakesParallelStream[String, Stream[String]]) =
6667
streamize(cc).parStream
@@ -78,14 +79,14 @@ package object generate {
7879
// Iterator
7980
def iI(j: Int)(implicit x: CC[Int] => Iterator[Int]) = x(cI(j))
8081
// Steppers (second letter--s = sequential, p = parallel)
81-
def tsI(j: Int)(implicit x: CC[Int] => MakesStepper[IntStepper]) = Sstep i cI(j)
82-
def tpI(j: Int)(implicit x: CC[Int] => MakesStepper[IntStepper with EfficientSubstep]) = Pstep i cI(j)
82+
def tsI(j: Int)(implicit x: CC[Int] => MakesStepper[Int, Any]) = Sstep i cI(j)
83+
def tpI(j: Int)(implicit x: CC[Int] => MakesStepper[Int, EfficientSubstep]) = Pstep i cI(j)
8384
// Streams
84-
def ssI(j: Int)(implicit x: CC[Int] => MakesSequentialStream[java.lang.Integer, IntStream]) = Sstream i cI(j)
85-
def spI(j: Int)(implicit x: CC[Int] => MakesParallelStream[java.lang.Integer, IntStream]) = Pstream i cI(j)
85+
def ssI(j: Int)(implicit x: CC[Int] => MakesSequentialStream[Int, IntStream]) = Sstream i cI(j)
86+
def spI(j: Int)(implicit x: CC[Int] => MakesParallelStream[Int, IntStream]) = Pstream i cI(j)
8687
// Streams via steppers
87-
def zsI(j: Int)(implicit x: CC[Int] => MakesStepper[IntStepper]) = SsStream i cI(j)
88-
def zpI(j: Int)(implicit x: CC[Int] => MakesStepper[IntStepper with EfficientSubstep]) = PsStream i cI(j)
88+
def zsI(j: Int)(implicit x: CC[Int] => MakesStepper[Int, Any]) = SsStream i cI(j)
89+
def zpI(j: Int)(implicit x: CC[Int] => MakesStepper[Int, EfficientSubstep]) = PsStream i cI(j)
8990
}
9091

9192
trait StringThingsOf[CC[_]] extends GenThingsOf[CC] {
@@ -95,14 +96,14 @@ package object generate {
9596
// Iterator
9697
def iS(j: Int)(implicit x: CC[String] => Iterator[String]) = x(cS(j))
9798
// Steppers (second letter--s = sequential, p = parallel)
98-
def tsS(j: Int)(implicit x: CC[String] => MakesStepper[AnyStepper[String]]) = Sstep s cS(j)
99-
def tpS(j: Int)(implicit x: CC[String] => MakesStepper[AnyStepper[String] with EfficientSubstep]) = Pstep s cS(j)
99+
def tsS(j: Int)(implicit x: CC[String] => MakesStepper[String, Any]) = Sstep s cS(j)
100+
def tpS(j: Int)(implicit x: CC[String] => MakesStepper[String, EfficientSubstep]) = Pstep s cS(j)
100101
// Streams
101102
def ssS(j: Int)(implicit x: CC[String] => MakesSequentialStream[String, Stream[String]]) = Sstream s cS(j)
102103
def spS(j: Int)(implicit x: CC[String] => MakesParallelStream[String, Stream[String]]) = Pstream s cS(j)
103104
// Streams via steppers
104-
def zsS(j: Int)(implicit x: CC[String] => MakesStepper[AnyStepper[String]]) = SsStream s cS(j)
105-
def zpS(j: Int)(implicit x: CC[String] => MakesStepper[AnyStepper[String] with EfficientSubstep]) = PsStream s cS(j)
105+
def zsS(j: Int)(implicit x: CC[String] => MakesStepper[String, Any]) = SsStream s cS(j)
106+
def zpS(j: Int)(implicit x: CC[String] => MakesStepper[String, EfficientSubstep]) = PsStream s cS(j)
106107
}
107108

108109
trait ThingsOf[CC[_]] extends IntThingsOf[CC] with StringThingsOf[CC] {}
@@ -158,16 +159,16 @@ package object generate {
158159

159160
// Streams from ArrayList (Java)
160161

161-
implicit val getsParStreamFromArrayListInt: (java.util.ArrayList[Int] => MakesParallelStream[java.lang.Integer, IntStream]) = ali => {
162-
new MakesParallelStream[java.lang.Integer, IntStream] {
162+
implicit val getsParStreamFromArrayListInt: (java.util.ArrayList[Int] => MakesParallelStream[Int, IntStream]) = ali => {
163+
new MakesParallelStream[Int, IntStream] {
163164
def parStream: IntStream = ali.
164165
asInstanceOf[java.util.ArrayList[java.lang.Integer]].
165166
parallelStream.parallel.
166167
mapToInt(new java.util.function.ToIntFunction[java.lang.Integer]{ def applyAsInt(i: java.lang.Integer) = i.intValue })
167168
}
168169
}
169-
implicit val getsSeqStreamFromArrayListInt: (java.util.ArrayList[Int] => MakesSequentialStream[java.lang.Integer, IntStream]) = ali => {
170-
new MakesSequentialStream[java.lang.Integer, IntStream] {
170+
implicit val getsSeqStreamFromArrayListInt: (java.util.ArrayList[Int] => MakesSequentialStream[Int, IntStream]) = ali => {
171+
new MakesSequentialStream[Int, IntStream] {
171172
def seqStream: IntStream = ali.
172173
asInstanceOf[java.util.ArrayList[java.lang.Integer]].
173174
stream().
@@ -187,16 +188,16 @@ package object generate {
187188

188189
// Streams from LinkedList (Java)
189190

190-
implicit val getsParStreamFromLinkedListInt: (java.util.LinkedList[Int] => MakesParallelStream[java.lang.Integer, IntStream]) = ali => {
191-
new MakesParallelStream[java.lang.Integer, IntStream] {
191+
implicit val getsParStreamFromLinkedListInt: (java.util.LinkedList[Int] => MakesParallelStream[Int, IntStream]) = ali => {
192+
new MakesParallelStream[Int, IntStream] {
192193
def parStream: IntStream = ali.
193194
asInstanceOf[java.util.LinkedList[java.lang.Integer]].
194195
parallelStream.parallel.
195196
mapToInt(new java.util.function.ToIntFunction[java.lang.Integer]{ def applyAsInt(i: java.lang.Integer) = i.intValue })
196197
}
197198
}
198-
implicit val getsSeqStreamFromLinkedListInt: (java.util.LinkedList[Int] => MakesSequentialStream[java.lang.Integer, IntStream]) = ali => {
199-
new MakesSequentialStream[java.lang.Integer, IntStream] {
199+
implicit val getsSeqStreamFromLinkedListInt: (java.util.LinkedList[Int] => MakesSequentialStream[Int, IntStream]) = ali => {
200+
new MakesSequentialStream[Int, IntStream] {
200201
def seqStream: IntStream = ali.
201202
asInstanceOf[java.util.LinkedList[java.lang.Integer]].
202203
stream().

benchmark/src/main/scala/bench/Operations.scala

+7-1
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,13 @@ object OnInt {
2727
def sum(t: Traversable[Int]): Int = t.sum
2828
def sum(i: Iterator[Int]): Int = i.sum
2929
def sum(s: IntStepper): Int = s.fold(0)(_ + _)
30-
def sum(s: IntStream): Int = s.sum
30+
def sum(s: IntStream): Int = {
31+
s.sum
32+
/*var r = 0
33+
val it = s.iterator()
34+
while(it.hasNext) r += it.nextInt()
35+
r*/
36+
}
3137
def psum(i: ParIterable[Int]): Int = i.sum
3238
def psum(s: IntStream): Int = s.sum
3339

benchmark/src/main/scala/bench/ParseJmhLog.scala

+2
Original file line numberDiff line numberDiff line change
@@ -143,4 +143,6 @@ object ParseJmhLog {
143143
println("-"*79)
144144
println
145145
}
146+
147+
def main(args: Array[String]): Unit = apply()
146148
}

src/main/java/scala/compat/java8/ScalaStreamSupport.java

+2-2
Original file line numberDiff line numberDiff line change
@@ -482,9 +482,9 @@ public static DoubleStream doubleStreamAccumulatedValues(scala.collection.Map<?,
482482
*/
483483
public static IntStream intStream(scala.collection.BitSet coll) {
484484
// Let the value class figure out the casting!
485-
scala.compat.java8.converterImpl.RichBitSetCanStep rbscs =
485+
scala.compat.java8.converterImpl.RichBitSetCanStep rbscs =
486486
new scala.compat.java8.converterImpl.RichBitSetCanStep(coll);
487-
return StreamSupport.intStream(rbscs.stepper(), false);
487+
return StreamSupport.intStream(rbscs.stepper(StepperShape$.MODULE$.intStepperShape()), false);
488488
}
489489

490490
/**

0 commit comments

Comments
 (0)