SlideShare a Scribd company logo
1 of 110
Download to read offline
Shooting the Rapids:
Getting the Best from Java 8
Streams
Kirk Pepperdine
@kcpeppe
Maurice Naftalin
@mauricenaftalin
About Kirk
• Specialises in performance tuning
• speaks frequently about performance
• author of performance tuning workshop
• Co-founder jClarity
• performance diagnositic tooling
• Java Champion (since 2006)
About Kirk
• Specialises in performance tuning
• speaks frequently about performance
• author of performance tuning workshop
• Co-founder jClarity
• performance diagnositic tooling
• Java Champion (since 2006)
About Maurice
About Maurice
About Maurice
Co-author Author
About Maurice
Co-author Author
Java
Champion
JavaOne
Rock Star
Agenda
Agenda
• Introduction
– lambdas, streams, and a logfile processing problem
Agenda
• Introduction
– lambdas, streams, and a logfile processing problem
• Optimizing stream sources
Agenda
• Introduction
– lambdas, streams, and a logfile processing problem
• Optimizing stream sources
• Tragedy Of The Commons
Agenda
• Introduction
– lambdas, streams, and a logfile processing problem
• Optimizing stream sources
• Tragedy Of The Commons
• Justifying the Overhead
Example: Processing GC Logfile
⋮
2.869: Application time: 1.0001540 seconds
5.342: Application time: 0.0801231 seconds
8.382: Application time: 1.1013574 seconds
⋮
Example: Processing GC Logfile
⋮
2.869: Application time: 1.0001540 seconds
5.342: Application time: 0.0801231 seconds
8.382: Application time: 1.1013574 seconds
⋮
sum=2.181635
Example: Processing GC Logfile
⋮
2.869: Application time: 1.0001540 seconds
5.342: Application time: 0.0801231 seconds
8.382: Application time: 1.1013574 seconds
⋮
Example: Processing GC Logfile
⋮
2.869: Application time: 1.0001540 seconds
5.342: Application time: 0.0801231 seconds
8.382: Application time: 1.1013574 seconds
⋮
DoubleSummaryStatistics
{count=3, sum=2.181635, min=0.080123, average=0.727212,
max=1.101357}
Application time: (d+.d+)
Example: Processing GC Logfile
⋮
2.869: Application time: 1.0001540 seconds
5.342: Application time: 0.0801231 seconds
8.382: Application time: 1.1013574 seconds
⋮
Regex:
Application time: (d+.d+)
Pattern stoppedTimePattern =
Pattern.compile(" ");
⋮
Matcher matcher = stoppedTimePattern.matcher(logRecord);
String value = matcher.group(1);
Example: Processing GC Logfile
Processing GC Logfile: Old School Code
Pattern stoppedTimePattern =
Pattern.compile("Application time: (d+.d+)");
String logRecord;

double value = 0;

while ( ( logRecord = logFileReader.readLine()) != null) {

Matcher matcher = stoppedTimePattern.matcher(logRecord);

if ( matcher.find()) {

value += (Double.parseDouble( matcher.group(1)));

}

}
Predicate<Matcher> matches = new Predicate<Matcher>() {

@Override

public boolean test(Matcher matcher) {

return matcher.find();

}

};
What is a Lambda?
matcher
matcher.find()
matcher
matcher.find()
Predicate<Matcher> matches = new Predicate<Matcher>() {

@Override

public boolean test(Matcher matcher) {

return matcher.find();

}

};
Predicate<Matcher> matches =
What is a Lambda?
matcher
matcher.find()
matcher
matcher.find()
Predicate<Matcher> matches = new Predicate<Matcher>() {

@Override

public boolean test(Matcher matcher) {

return matcher.find();

}

};
Predicate<Matcher> matches =
What is a Lambda?
matcher
Predicate<Matcher> matches =
matcher.find()
matcher
matcher.find()
Predicate<Matcher> matches = new Predicate<Matcher>() {

@Override

public boolean test(Matcher matcher) {

return matcher.find();

}

};
Predicate<Matcher> matches =
What is a Lambda?
matcherPredicate<Matcher> matches =
matcher.find()
matcher
matcher.find()
Predicate<Matcher> matches = new Predicate<Matcher>() {

@Override

public boolean test(Matcher matcher) {

return matcher.find();

}

};
Predicate<Matcher> matches =
What is a Lambda?
matcherPredicate<Matcher> matches =
matcher.find()
->
matcher
matcher.find()
Predicate<Matcher> matches = new Predicate<Matcher>() {

@Override

public boolean test(Matcher matcher) {

return matcher.find();

}

};
Predicate<Matcher> matches =
What is a Lambda?
matcherPredicate<Matcher> matches = matcher.find()->
matcher
matcher.find()
Predicate<Matcher> matches = new Predicate<Matcher>() {

@Override

public boolean test(Matcher matcher) {

return matcher.find();

}

};
Predicate<Matcher> matches =
What is a Lambda?
matcherPredicate<Matcher> matches =
A lambda is a function
from arguments to result
matcher.find()->
matcher
matcher.find()
Processing Logfile: Stream Code
DoubleSummaryStatistics summaryStatistics =

logFileReader.lines()

.map(input -> stoppedTimePattern.matcher(input))

.filter(matcher -> matcher.find())

.map(matcher -> matcher.group(1))

.mapToDouble(s -> Double.parseDouble(s))

.summaryStatistics();

Processing Logfile: Stream Code
DoubleSummaryStatistics summaryStatistics =

logFileReader.lines()

.map(input -> stoppedTimePattern.matcher(input))

.filter(matcher -> matcher.find())

.map(matcher -> matcher.group(1))

.mapToDouble(s -> Double.parseDouble(s))

.summaryStatistics();

data source
Processing Logfile: Stream Code
DoubleSummaryStatistics summaryStatistics =

logFileReader.lines()

.map(input -> stoppedTimePattern.matcher(input))

.filter(matcher -> matcher.find())

.map(matcher -> matcher.group(1))

.mapToDouble(s -> Double.parseDouble(s))

.summaryStatistics();

start streaming
Processing Logfile: Stream Code
DoubleSummaryStatistics summaryStatistics =

logFileReader.lines()

.map(input -> stoppedTimePattern.matcher(input))

.filter(matcher -> matcher.find())

.map(matcher -> matcher.group(1))

.mapToDouble(s -> Double.parseDouble(s))

.summaryStatistics();

map to Matcher
Processing Logfile: Stream Code
DoubleSummaryStatistics summaryStatistics =

logFileReader.lines()

.map(input -> stoppedTimePattern.matcher(input))

.filter(matcher -> matcher.find())

.map(matcher -> matcher.group(1))

.mapToDouble(s -> Double.parseDouble(s))

.summaryStatistics();

filter out
uninteresting bits
Processing Logfile: Stream Code
DoubleSummaryStatistics summaryStatistics =

logFileReader.lines()

.map(input -> stoppedTimePattern.matcher(input))

.filter(matcher -> matcher.find())

.map(matcher -> matcher.group(1))

.mapToDouble(s -> Double.parseDouble(s))

.summaryStatistics();

extract group
Processing Logfile: Stream Code
DoubleSummaryStatistics summaryStatistics =

logFileReader.lines()

.map(input -> stoppedTimePattern.matcher(input))

.filter(matcher -> matcher.find())

.map(matcher -> matcher.group(1))

.mapToDouble(s -> Double.parseDouble(s))

.summaryStatistics();

map String to
Double
Processing Logfile: Stream Code
DoubleSummaryStatistics summaryStatistics =

logFileReader.lines()

.map(input -> stoppedTimePattern.matcher(input))

.filter(matcher -> matcher.find())

.map(matcher -> matcher.group(1))

.mapToDouble(s -> Double.parseDouble(s))

.summaryStatistics();

aggregate results
What is a Stream?
• A sequence of values
• source and intermediate operations set the stream up lazily:
Stream<String> groupStream =

logFileReader.lines()

.map(stoppedTimePattern::matcher)

.filter(Matcher::find)

.map(matcher -> matcher.group(1))
.mapToDouble(Double::parseDouble);
Source
What is a Stream?
• A sequence of values
• source and intermediate operations set the stream up lazily:
Stream<String> groupStream =

logFileReader.lines()

.map(stoppedTimePattern::matcher)

.filter(Matcher::find)

.map(matcher -> matcher.group(1))
.mapToDouble(Double::parseDouble);
Intermediate
Operations
What is a Stream?
• The terminal operation pulls the values down the stream:
SummaryStatistics statistics =

logFileReader.lines()

.map(stoppedTimePattern::matcher)

.filter(Matcher::find)

.map(matcher -> matcher.group(1))
.mapToDouble(Double::parseDouble)
.summaryStatistics();Terminal
Operation
Visualising Sequential Streams
x2x0 x1 x3x0 x1 x2 x3
Source Map Filter Reduction
Intermediate
Operations
Terminal
Operation
“Values in Motion”
Visualising Sequential Streams
x2x0 x1 x3x1 x2 x3 ✔
Source Map Filter Reduction
Intermediate
Operations
Terminal
Operation
“Values in Motion”
Visualising Sequential Streams
x2x0 x1 x3 x1x2 x3 ❌✔
Source Map Filter Reduction
Intermediate
Operations
Terminal
Operation
“Values in Motion”
Visualising Sequential Streams
x2x0 x1 x3 x1x2x3 ❌✔
Source Map Filter Reduction
Intermediate
Operations
Terminal
Operation
“Values in Motion”
Old School: 80200ms
Sequential: 25800ms
(>9m lines, MacBook Pro, Haswell i7, 4 cores, hyperthreaded)
Stream code is faster because operations are fused
How Does That Perform?
Can We Do Better?
Parallel streams make use of multiple cores
• split the data into segments
• each segment processed by its own thread
- on its own core – if possible
Splitting the Data
Implemented by a Spliterator:
Splitting the Data
Implemented by a Spliterator:
Splitting the Data
Implemented by a Spliterator:
Splitting the Data
Implemented by a Spliterator:
Splitting the Data
Implemented by a Spliterator:
Splitting the Data
Implemented by a Spliterator:
Splitting the Data
Implemented by a Spliterator:
Splitting the Data
Implemented by a Spliterator:
Splitting the Data
Implemented by a Spliterator:
x2
Visualizing Parallel Streams
x0
x1
x3
x0
x1
x2
x3
x2
Visualizing Parallel Streams
x0
x1
x3
x0
x1
x2
x3
x2
Visualizing Parallel Streams
x1
x3
x0
x1
x3
✔
❌
x2
Visualizing Parallel Streams
x1 y3
x0
x1
x3
✔
❌
Stream Code
DoubleSummaryStatistics summaryStatistics =

logFileReader.lines().parallel()

.map(stoppedTimePattern::matcher)

.filter(Matcher::find)

.map(matcher -> matcher.group(1))

.mapToDouble(Double::parseDouble)

.summaryStatistics();
Results of Going Parallel:
• No benefit from using parallel streams while streaming data
Agenda
Agenda
• Introduction
– lambdas, streams, and a logfile processing problem
Agenda
• Introduction
– lambdas, streams, and a logfile processing problem
• Optimizing stream sources
Agenda
• Introduction
– lambdas, streams, and a logfile processing problem
• Optimizing stream sources
• Tragedy Of The Commons
Agenda
• Introduction
– lambdas, streams, and a logfile processing problem
• Optimizing stream sources
• Tragedy Of The Commons
• Justifying the Overhead
Poorly Splitting Sources
• Some sources split much worse than others
– LinkedList vs. ArrayList
Poorly Splitting Sources
• Some sources split much worse than others
– LinkedList vs. ArrayList
• Streaming I/O is bad.
– kills the advantage of going parallel
Poorly Splitting Sources
• Some sources split much worse than others
– LinkedList vs. ArrayList
• Streaming I/O is bad.
– kills the advantage of going parallel
Poorly Splitting Sources
Streaming I/O Bottleneck
x2x0 x1 x3x0 x1 x2 x3
Streaming I/O Bottleneck
✔
❌
x2x1x0 x1 x3
5.342: … nds
LineSpliterator
2.869:Applicati … seconds n 8.382: … nds 9.337:App … ndsn n n
spliterator coverage
5.342: … nds
LineSpliterator
2.869:Applicati … seconds n 8.382: … nds 9.337:App … ndsn n n
spliterator coverage
MappedByteBuffer
5.342: … nds
LineSpliterator
2.869:Applicati … seconds n 8.382: … nds 9.337:App … ndsn n n
spliterator coverage
MappedByteBuffer mid
5.342: … nds
LineSpliterator
2.869:Applicati … seconds n 8.382: … nds 9.337:App … ndsn n n
spliterator coverage
MappedByteBuffer mid
5.342: … nds
LineSpliterator
2.869:Applicati … seconds n 8.382: … nds 9.337:App … ndsn n n
spliterator coveragenew spliterator coverage
MappedByteBuffer mid
5.342: … nds
LineSpliterator
2.869:Applicati … seconds n 8.382: … nds 9.337:App … ndsn n n
spliterator coveragenew spliterator coverage
MappedByteBuffer mid
Included in JDK9 as FileChannelLinesSpliterator
StreamingIO: 56s
Spliterator: 88s
(>9m lines, MacBook Pro, Haswell i7, 4 cores, hyperthreaded)
Stream code is faster because operations are fused
LineSpliterator – results
When to Use Parallel Streams?
When to Use Parallel Streams?
• Task must be recursively decomposable
– subtasks for each data segment must be independent
When to Use Parallel Streams?
• Task must be recursively decomposable
– subtasks for each data segment must be independent
• Source must be well-splitting
When to Use Parallel Streams?
• Task must be recursively decomposable
– subtasks for each data segment must be independent
• Source must be well-splitting
• Enough hardware to support allVM needs
– there may be other business afoot
When to Use Parallel Streams?
• Task must be recursively decomposable
– subtasks for each data segment must be independent
• Source must be well-splitting
• Enough hardware to support allVM needs
– there may be other business afoot
• Overhead of splitting must be justified
– intermediate operations need to be expensive
– and CPU-bound
When to Use Parallel Streams?
• Task must be recursively decomposable
– subtasks for each data segment must be independent
• Source must be well-splitting
• Enough hardware to support allVM needs
– there may be other business afoot
• Overhead of splitting must be justified
– intermediate operations need to be expensive
– and CPU-bound
http://gee.cs.oswego.edu/dl/html/StreamParallelGuidance.html
Agenda
Agenda
• Introduction
– lambdas, streams, and a logfile processing problem
Agenda
• Introduction
– lambdas, streams, and a logfile processing problem
• Optimizing stream sources
Agenda
• Introduction
– lambdas, streams, and a logfile processing problem
• Optimizing stream sources
• Tragedy Of The Commons
Agenda
• Introduction
– lambdas, streams, and a logfile processing problem
• Optimizing stream sources
• Tragedy Of The Commons
• Justifying the Overhead
Tragedy of the Commons
Tragedy of the Commons
You have a finite amount of hardware
– it might be in your best interest to grab it all
– but if everyone behaves the same way…
Agenda
Agenda
• Introduction
– lambdas, streams, and a logfile processing problem
Agenda
• Introduction
– lambdas, streams, and a logfile processing problem
• Optimizing stream sources
Agenda
• Introduction
– lambdas, streams, and a logfile processing problem
• Optimizing stream sources
• Tragedy Of The Commons
Agenda
• Introduction
– lambdas, streams, and a logfile processing problem
• Optimizing stream sources
• Tragedy Of The Commons
• Justifying the Overhead
Justifying the Overhead
CPNQ performance model:
C - number of submitters
P - number of CPUs
N - number of elements
Q - cost of the operation
Justifying the Overhead
Need to amortize setup costs
– N*Q needs to be large
– Q can often only be estimated
– N often should be >10,000 elements
If P is the number of processors, the formula assumes that
intermediate tasks are CPU bound
Don’t Have Too Many Threads!
• Too many threads cause frequent handoffs
• It costs ~80,000 cycles to handoff data between threads
• You can do a lot of processing in 80,000 cycles!
Fork/Join
Fork/Join
• Parallel streams implemented by Fork/Join framework
• added in Java 7, but difficult to code
• parallel streams are more usable
Fork/Join
• Parallel streams implemented by Fork/Join framework
• added in Java 7, but difficult to code
• parallel streams are more usable
Fork/Join
• Parallel streams implemented by Fork/Join framework
• added in Java 7, but difficult to code
• parallel streams are more usable
• Each segment of data is submitted as a ForkJoinTask
• ForkJoinTask.invoke() spawns a new task
• ForkJoinTask.join() retrieves the result
Fork/Join
• Parallel streams implemented by Fork/Join framework
• added in Java 7, but difficult to code
• parallel streams are more usable
• Each segment of data is submitted as a ForkJoinTask
• ForkJoinTask.invoke() spawns a new task
• ForkJoinTask.join() retrieves the result
• How Fork/Join works and performs is important to your
latency picture
Common Fork/Join Pool
Fork/Join by default uses a common thread pool
- default number of worker threads == number of logical cores - 1
- (submitting thread is pressed into service)
- can configure the pool via system properties:
- or create our own pool…
java.util.concurrent.ForkJoinPool.common.parallelism

java.util.concurrent.ForkJoinPool.common.threadFactory

java.util.concurrent.ForkJoinPool.common.exceptionHandler
Custom Fork/Join Pool
When used inside a ForkJoinPool, the ForkJoinTask.fork()
method uses the current pool:
ForkJoinPool ourOwnPool = new ForkJoinPool(10);
ourOwnPool.invoke(
() -> stream.parallel().
⋮
Don’t Have Too Few Threads!
• Fork/Join pool uses a work queue
• If tasks are CPU bound, no use increasing the size of the
thread pool
• But if not CPU bound, they are sitting in queue
accumulating dead time
• Can make thread pool bigger to reduce dead time
• Little’s Law tells us
Number of tasks in the system =

Arrival rate * Average service time
Little’s Law Example
System receives 400 Txs and it takes 100ms to clear a request
- Number of tasks in system = 0.100 * 400 = 40
On an 8 core machine with a CPU bound task
- implies 32 tasks are sitting in queue accumulating dead time
- Average response time 600 ms of which 500ms is dead time
- ~83% of service time is in waiting
public final V invoke() {
ForkJoinPool.common.getMonitor().submitTask(this);
int s;
if ((s = doInvoke() & DONE_MASK) != NORMAL) reportException(s);
ForkJoinPool.common.getMonitor().retireTask(this);
return getRawResult();
}
ForkJoinPool Observability
ForkJoinPool comes with no visibility
- need to instrument ForkJoinTask.invoke()
– gather data from ForkJoinPool to feed into Little’s Law
Conclusions
Sequential stream performance comparable to imperative code
Going parallel is worthwhile IF
- task is suitable
- data source is suitable
- environment is suitable
Need to monitor JDK to understanding bottlenecks
- Fork/Join pool is not well instrumented
Questions?
Questions?

More Related Content

What's hot

Effective testing for spark programs Strata NY 2015
Effective testing for spark programs   Strata NY 2015Effective testing for spark programs   Strata NY 2015
Effective testing for spark programs Strata NY 2015Holden Karau
 
Beyond parallelize and collect - Spark Summit East 2016
Beyond parallelize and collect - Spark Summit East 2016Beyond parallelize and collect - Spark Summit East 2016
Beyond parallelize and collect - Spark Summit East 2016Holden Karau
 
Unit testing of spark applications
Unit testing of spark applicationsUnit testing of spark applications
Unit testing of spark applicationsKnoldus Inc.
 
Weaving Dataflows with Silk - ScalaMatsuri 2014, Tokyo
Weaving Dataflows with Silk - ScalaMatsuri 2014, TokyoWeaving Dataflows with Silk - ScalaMatsuri 2014, Tokyo
Weaving Dataflows with Silk - ScalaMatsuri 2014, TokyoTaro L. Saito
 
Kotlin @ Coupang Backed - JetBrains Day seoul 2018
Kotlin @ Coupang Backed - JetBrains Day seoul 2018Kotlin @ Coupang Backed - JetBrains Day seoul 2018
Kotlin @ Coupang Backed - JetBrains Day seoul 2018Sunghyouk Bae
 
Introduction of failsafe
Introduction of failsafeIntroduction of failsafe
Introduction of failsafeSunghyouk Bae
 
Apache Spark Structured Streaming for Machine Learning - StrataConf 2016
Apache Spark Structured Streaming for Machine Learning - StrataConf 2016Apache Spark Structured Streaming for Machine Learning - StrataConf 2016
Apache Spark Structured Streaming for Machine Learning - StrataConf 2016Holden Karau
 
Improving PySpark Performance - Spark Beyond the JVM @ PyData DC 2016
Improving PySpark Performance - Spark Beyond the JVM @ PyData DC 2016Improving PySpark Performance - Spark Beyond the JVM @ PyData DC 2016
Improving PySpark Performance - Spark Beyond the JVM @ PyData DC 2016Holden Karau
 
Ge aviation spark application experience porting analytics into py spark ml p...
Ge aviation spark application experience porting analytics into py spark ml p...Ge aviation spark application experience porting analytics into py spark ml p...
Ge aviation spark application experience porting analytics into py spark ml p...Databricks
 
Kotlin @ Coupang Backend 2017
Kotlin @ Coupang Backend 2017Kotlin @ Coupang Backend 2017
Kotlin @ Coupang Backend 2017Sunghyouk Bae
 
Testing and validating spark programs - Strata SJ 2016
Testing and validating spark programs - Strata SJ 2016Testing and validating spark programs - Strata SJ 2016
Testing and validating spark programs - Strata SJ 2016Holden Karau
 
HBase RowKey design for Akka Persistence
HBase RowKey design for Akka PersistenceHBase RowKey design for Akka Persistence
HBase RowKey design for Akka PersistenceKonrad Malawski
 
Effective testing for spark programs scala bay preview (pre-strata ny 2015)
Effective testing for spark programs scala bay preview (pre-strata ny 2015)Effective testing for spark programs scala bay preview (pre-strata ny 2015)
Effective testing for spark programs scala bay preview (pre-strata ny 2015)Holden Karau
 
Beyond Shuffling - Effective Tips and Tricks for Scaling Spark (Vancouver Sp...
Beyond Shuffling  - Effective Tips and Tricks for Scaling Spark (Vancouver Sp...Beyond Shuffling  - Effective Tips and Tricks for Scaling Spark (Vancouver Sp...
Beyond Shuffling - Effective Tips and Tricks for Scaling Spark (Vancouver Sp...Holden Karau
 
Reactive Streams / Akka Streams - GeeCON Prague 2014
Reactive Streams / Akka Streams - GeeCON Prague 2014Reactive Streams / Akka Streams - GeeCON Prague 2014
Reactive Streams / Akka Streams - GeeCON Prague 2014Konrad Malawski
 
2014 akka-streams-tokyo-japanese
2014 akka-streams-tokyo-japanese2014 akka-streams-tokyo-japanese
2014 akka-streams-tokyo-japaneseKonrad Malawski
 
Getting the best performance with PySpark - Spark Summit West 2016
Getting the best performance with PySpark - Spark Summit West 2016Getting the best performance with PySpark - Spark Summit West 2016
Getting the best performance with PySpark - Spark Summit West 2016Holden Karau
 
Algebird : Abstract Algebra for big data analytics. Devoxx 2014
Algebird : Abstract Algebra for big data analytics. Devoxx 2014Algebird : Abstract Algebra for big data analytics. Devoxx 2014
Algebird : Abstract Algebra for big data analytics. Devoxx 2014Samir Bessalah
 

What's hot (20)

Effective testing for spark programs Strata NY 2015
Effective testing for spark programs   Strata NY 2015Effective testing for spark programs   Strata NY 2015
Effective testing for spark programs Strata NY 2015
 
Beyond parallelize and collect - Spark Summit East 2016
Beyond parallelize and collect - Spark Summit East 2016Beyond parallelize and collect - Spark Summit East 2016
Beyond parallelize and collect - Spark Summit East 2016
 
Unit testing of spark applications
Unit testing of spark applicationsUnit testing of spark applications
Unit testing of spark applications
 
Weaving Dataflows with Silk - ScalaMatsuri 2014, Tokyo
Weaving Dataflows with Silk - ScalaMatsuri 2014, TokyoWeaving Dataflows with Silk - ScalaMatsuri 2014, Tokyo
Weaving Dataflows with Silk - ScalaMatsuri 2014, Tokyo
 
Kotlin @ Coupang Backed - JetBrains Day seoul 2018
Kotlin @ Coupang Backed - JetBrains Day seoul 2018Kotlin @ Coupang Backed - JetBrains Day seoul 2018
Kotlin @ Coupang Backed - JetBrains Day seoul 2018
 
Introduction of failsafe
Introduction of failsafeIntroduction of failsafe
Introduction of failsafe
 
Apache Spark Structured Streaming for Machine Learning - StrataConf 2016
Apache Spark Structured Streaming for Machine Learning - StrataConf 2016Apache Spark Structured Streaming for Machine Learning - StrataConf 2016
Apache Spark Structured Streaming for Machine Learning - StrataConf 2016
 
Graphite
GraphiteGraphite
Graphite
 
Improving PySpark Performance - Spark Beyond the JVM @ PyData DC 2016
Improving PySpark Performance - Spark Beyond the JVM @ PyData DC 2016Improving PySpark Performance - Spark Beyond the JVM @ PyData DC 2016
Improving PySpark Performance - Spark Beyond the JVM @ PyData DC 2016
 
Ge aviation spark application experience porting analytics into py spark ml p...
Ge aviation spark application experience porting analytics into py spark ml p...Ge aviation spark application experience porting analytics into py spark ml p...
Ge aviation spark application experience porting analytics into py spark ml p...
 
Kotlin @ Coupang Backend 2017
Kotlin @ Coupang Backend 2017Kotlin @ Coupang Backend 2017
Kotlin @ Coupang Backend 2017
 
Testing and validating spark programs - Strata SJ 2016
Testing and validating spark programs - Strata SJ 2016Testing and validating spark programs - Strata SJ 2016
Testing and validating spark programs - Strata SJ 2016
 
HBase RowKey design for Akka Persistence
HBase RowKey design for Akka PersistenceHBase RowKey design for Akka Persistence
HBase RowKey design for Akka Persistence
 
Effective testing for spark programs scala bay preview (pre-strata ny 2015)
Effective testing for spark programs scala bay preview (pre-strata ny 2015)Effective testing for spark programs scala bay preview (pre-strata ny 2015)
Effective testing for spark programs scala bay preview (pre-strata ny 2015)
 
Beyond Shuffling - Effective Tips and Tricks for Scaling Spark (Vancouver Sp...
Beyond Shuffling  - Effective Tips and Tricks for Scaling Spark (Vancouver Sp...Beyond Shuffling  - Effective Tips and Tricks for Scaling Spark (Vancouver Sp...
Beyond Shuffling - Effective Tips and Tricks for Scaling Spark (Vancouver Sp...
 
Requery overview
Requery overviewRequery overview
Requery overview
 
Reactive Streams / Akka Streams - GeeCON Prague 2014
Reactive Streams / Akka Streams - GeeCON Prague 2014Reactive Streams / Akka Streams - GeeCON Prague 2014
Reactive Streams / Akka Streams - GeeCON Prague 2014
 
2014 akka-streams-tokyo-japanese
2014 akka-streams-tokyo-japanese2014 akka-streams-tokyo-japanese
2014 akka-streams-tokyo-japanese
 
Getting the best performance with PySpark - Spark Summit West 2016
Getting the best performance with PySpark - Spark Summit West 2016Getting the best performance with PySpark - Spark Summit West 2016
Getting the best performance with PySpark - Spark Summit West 2016
 
Algebird : Abstract Algebra for big data analytics. Devoxx 2014
Algebird : Abstract Algebra for big data analytics. Devoxx 2014Algebird : Abstract Algebra for big data analytics. Devoxx 2014
Algebird : Abstract Algebra for big data analytics. Devoxx 2014
 

Similar to Shooting the Rapids: Getting the Best from Java 8 Streams

What's new in Java 8
What's new in Java 8What's new in Java 8
What's new in Java 8Kyle Smith
 
New Features in JDK 8
New Features in JDK 8New Features in JDK 8
New Features in JDK 8Martin Toshev
 
Eclipse Day India 2015 - Java 8 Overview
Eclipse Day India 2015 - Java 8 OverviewEclipse Day India 2015 - Java 8 Overview
Eclipse Day India 2015 - Java 8 OverviewEclipse Day India
 
New features in jdk8 iti
New features in jdk8 itiNew features in jdk8 iti
New features in jdk8 itiAhmed mar3y
 
Charles Sharp: Java 8 Streams
Charles Sharp: Java 8 StreamsCharles Sharp: Java 8 Streams
Charles Sharp: Java 8 Streamsjessitron
 
Beyond Java: 자바 8을 중심으로 본 자바의 혁신
Beyond Java: 자바 8을 중심으로 본 자바의 혁신Beyond Java: 자바 8을 중심으로 본 자바의 혁신
Beyond Java: 자바 8을 중심으로 본 자바의 혁신Sungchul Park
 
Spark Summit EU talk by Herman van Hovell
Spark Summit EU talk by Herman van HovellSpark Summit EU talk by Herman van Hovell
Spark Summit EU talk by Herman van HovellSpark Summit
 
Lambda Chops - Recipes for Simpler, More Expressive Code
Lambda Chops - Recipes for Simpler, More Expressive CodeLambda Chops - Recipes for Simpler, More Expressive Code
Lambda Chops - Recipes for Simpler, More Expressive CodeIan Robertson
 
Real Time Big Data Management
Real Time Big Data ManagementReal Time Big Data Management
Real Time Big Data ManagementAlbert Bifet
 
Belfast JUG 23-10-2013
Belfast JUG 23-10-2013Belfast JUG 23-10-2013
Belfast JUG 23-10-2013eamonnlong
 
A brief tour of modern Java
A brief tour of modern JavaA brief tour of modern Java
A brief tour of modern JavaSina Madani
 
Apache Calcite: A Foundational Framework for Optimized Query Processing Over ...
Apache Calcite: A Foundational Framework for Optimized Query Processing Over ...Apache Calcite: A Foundational Framework for Optimized Query Processing Over ...
Apache Calcite: A Foundational Framework for Optimized Query Processing Over ...Julian Hyde
 
Exploring Streams and Lambdas in Java8
Exploring Streams and Lambdas in Java8Exploring Streams and Lambdas in Java8
Exploring Streams and Lambdas in Java8Isuru Samaraweera
 
Distributed Real-Time Stream Processing: Why and How 2.0
Distributed Real-Time Stream Processing:  Why and How 2.0Distributed Real-Time Stream Processing:  Why and How 2.0
Distributed Real-Time Stream Processing: Why and How 2.0Petr Zapletal
 

Similar to Shooting the Rapids: Getting the Best from Java 8 Streams (20)

What's new in Java 8
What's new in Java 8What's new in Java 8
What's new in Java 8
 
New Features in JDK 8
New Features in JDK 8New Features in JDK 8
New Features in JDK 8
 
Eclipse Day India 2015 - Java 8 Overview
Eclipse Day India 2015 - Java 8 OverviewEclipse Day India 2015 - Java 8 Overview
Eclipse Day India 2015 - Java 8 Overview
 
New features in jdk8 iti
New features in jdk8 itiNew features in jdk8 iti
New features in jdk8 iti
 
Solr @ Etsy - Apache Lucene Eurocon
Solr @ Etsy - Apache Lucene EuroconSolr @ Etsy - Apache Lucene Eurocon
Solr @ Etsy - Apache Lucene Eurocon
 
Charles Sharp: Java 8 Streams
Charles Sharp: Java 8 StreamsCharles Sharp: Java 8 Streams
Charles Sharp: Java 8 Streams
 
Beyond Java: 자바 8을 중심으로 본 자바의 혁신
Beyond Java: 자바 8을 중심으로 본 자바의 혁신Beyond Java: 자바 8을 중심으로 본 자바의 혁신
Beyond Java: 자바 8을 중심으로 본 자바의 혁신
 
Lambdas and Laughs
Lambdas and LaughsLambdas and Laughs
Lambdas and Laughs
 
Spark Summit EU talk by Herman van Hovell
Spark Summit EU talk by Herman van HovellSpark Summit EU talk by Herman van Hovell
Spark Summit EU talk by Herman van Hovell
 
Lambda Chops - Recipes for Simpler, More Expressive Code
Lambda Chops - Recipes for Simpler, More Expressive CodeLambda Chops - Recipes for Simpler, More Expressive Code
Lambda Chops - Recipes for Simpler, More Expressive Code
 
Javantura v4 - Java and lambdas and streams - are they better than for loops ...
Javantura v4 - Java and lambdas and streams - are they better than for loops ...Javantura v4 - Java and lambdas and streams - are they better than for loops ...
Javantura v4 - Java and lambdas and streams - are they better than for loops ...
 
Real Time Big Data Management
Real Time Big Data ManagementReal Time Big Data Management
Real Time Big Data Management
 
Java 8
Java 8Java 8
Java 8
 
Belfast JUG 23-10-2013
Belfast JUG 23-10-2013Belfast JUG 23-10-2013
Belfast JUG 23-10-2013
 
Java gets a closure
Java gets a closureJava gets a closure
Java gets a closure
 
A brief tour of modern Java
A brief tour of modern JavaA brief tour of modern Java
A brief tour of modern Java
 
Apache Calcite: A Foundational Framework for Optimized Query Processing Over ...
Apache Calcite: A Foundational Framework for Optimized Query Processing Over ...Apache Calcite: A Foundational Framework for Optimized Query Processing Over ...
Apache Calcite: A Foundational Framework for Optimized Query Processing Over ...
 
Exploring Streams and Lambdas in Java8
Exploring Streams and Lambdas in Java8Exploring Streams and Lambdas in Java8
Exploring Streams and Lambdas in Java8
 
Java8lambda
Java8lambda Java8lambda
Java8lambda
 
Distributed Real-Time Stream Processing: Why and How 2.0
Distributed Real-Time Stream Processing:  Why and How 2.0Distributed Real-Time Stream Processing:  Why and How 2.0
Distributed Real-Time Stream Processing: Why and How 2.0
 

Recently uploaded

Balasore Best It Company|| Top 10 IT Company || Balasore Software company Odisha
Balasore Best It Company|| Top 10 IT Company || Balasore Software company OdishaBalasore Best It Company|| Top 10 IT Company || Balasore Software company Odisha
Balasore Best It Company|| Top 10 IT Company || Balasore Software company Odishasmiwainfosol
 
Odoo 14 - eLearning Module In Odoo 14 Enterprise
Odoo 14 - eLearning Module In Odoo 14 EnterpriseOdoo 14 - eLearning Module In Odoo 14 Enterprise
Odoo 14 - eLearning Module In Odoo 14 Enterprisepreethippts
 
VK Business Profile - provides IT solutions and Web Development
VK Business Profile - provides IT solutions and Web DevelopmentVK Business Profile - provides IT solutions and Web Development
VK Business Profile - provides IT solutions and Web Developmentvyaparkranti
 
Alfresco TTL#157 - Troubleshooting Made Easy: Deciphering Alfresco mTLS Confi...
Alfresco TTL#157 - Troubleshooting Made Easy: Deciphering Alfresco mTLS Confi...Alfresco TTL#157 - Troubleshooting Made Easy: Deciphering Alfresco mTLS Confi...
Alfresco TTL#157 - Troubleshooting Made Easy: Deciphering Alfresco mTLS Confi...Angel Borroy López
 
Introduction Computer Science - Software Design.pdf
Introduction Computer Science - Software Design.pdfIntroduction Computer Science - Software Design.pdf
Introduction Computer Science - Software Design.pdfFerryKemperman
 
Folding Cheat Sheet #4 - fourth in a series
Folding Cheat Sheet #4 - fourth in a seriesFolding Cheat Sheet #4 - fourth in a series
Folding Cheat Sheet #4 - fourth in a seriesPhilip Schwarz
 
MYjobs Presentation Django-based project
MYjobs Presentation Django-based projectMYjobs Presentation Django-based project
MYjobs Presentation Django-based projectAnoyGreter
 
Intelligent Home Wi-Fi Solutions | ThinkPalm
Intelligent Home Wi-Fi Solutions | ThinkPalmIntelligent Home Wi-Fi Solutions | ThinkPalm
Intelligent Home Wi-Fi Solutions | ThinkPalmSujith Sukumaran
 
Global Identity Enrolment and Verification Pro Solution - Cizo Technology Ser...
Global Identity Enrolment and Verification Pro Solution - Cizo Technology Ser...Global Identity Enrolment and Verification Pro Solution - Cizo Technology Ser...
Global Identity Enrolment and Verification Pro Solution - Cizo Technology Ser...Cizo Technology Services
 
cpct NetworkING BASICS AND NETWORK TOOL.ppt
cpct NetworkING BASICS AND NETWORK TOOL.pptcpct NetworkING BASICS AND NETWORK TOOL.ppt
cpct NetworkING BASICS AND NETWORK TOOL.pptrcbcrtm
 
SuccessFactors 1H 2024 Release - Sneak-Peek by Deloitte Germany
SuccessFactors 1H 2024 Release - Sneak-Peek by Deloitte GermanySuccessFactors 1H 2024 Release - Sneak-Peek by Deloitte Germany
SuccessFactors 1H 2024 Release - Sneak-Peek by Deloitte GermanyChristoph Pohl
 
Maximizing Efficiency and Profitability with OnePlan’s Professional Service A...
Maximizing Efficiency and Profitability with OnePlan’s Professional Service A...Maximizing Efficiency and Profitability with OnePlan’s Professional Service A...
Maximizing Efficiency and Profitability with OnePlan’s Professional Service A...OnePlan Solutions
 
CRM Contender Series: HubSpot vs. Salesforce
CRM Contender Series: HubSpot vs. SalesforceCRM Contender Series: HubSpot vs. Salesforce
CRM Contender Series: HubSpot vs. SalesforceBrainSell Technologies
 
Tech Tuesday - Mastering Time Management Unlock the Power of OnePlan's Timesh...
Tech Tuesday - Mastering Time Management Unlock the Power of OnePlan's Timesh...Tech Tuesday - Mastering Time Management Unlock the Power of OnePlan's Timesh...
Tech Tuesday - Mastering Time Management Unlock the Power of OnePlan's Timesh...OnePlan Solutions
 
办理学位证(UQ文凭证书)昆士兰大学毕业证成绩单原版一模一样
办理学位证(UQ文凭证书)昆士兰大学毕业证成绩单原版一模一样办理学位证(UQ文凭证书)昆士兰大学毕业证成绩单原版一模一样
办理学位证(UQ文凭证书)昆士兰大学毕业证成绩单原版一模一样umasea
 
Machine Learning Software Engineering Patterns and Their Engineering
Machine Learning Software Engineering Patterns and Their EngineeringMachine Learning Software Engineering Patterns and Their Engineering
Machine Learning Software Engineering Patterns and Their EngineeringHironori Washizaki
 
Exploring Selenium_Appium Frameworks for Seamless Integration with HeadSpin.pdf
Exploring Selenium_Appium Frameworks for Seamless Integration with HeadSpin.pdfExploring Selenium_Appium Frameworks for Seamless Integration with HeadSpin.pdf
Exploring Selenium_Appium Frameworks for Seamless Integration with HeadSpin.pdfkalichargn70th171
 
What is Fashion PLM and Why Do You Need It
What is Fashion PLM and Why Do You Need ItWhat is Fashion PLM and Why Do You Need It
What is Fashion PLM and Why Do You Need ItWave PLM
 

Recently uploaded (20)

Balasore Best It Company|| Top 10 IT Company || Balasore Software company Odisha
Balasore Best It Company|| Top 10 IT Company || Balasore Software company OdishaBalasore Best It Company|| Top 10 IT Company || Balasore Software company Odisha
Balasore Best It Company|| Top 10 IT Company || Balasore Software company Odisha
 
Odoo 14 - eLearning Module In Odoo 14 Enterprise
Odoo 14 - eLearning Module In Odoo 14 EnterpriseOdoo 14 - eLearning Module In Odoo 14 Enterprise
Odoo 14 - eLearning Module In Odoo 14 Enterprise
 
VK Business Profile - provides IT solutions and Web Development
VK Business Profile - provides IT solutions and Web DevelopmentVK Business Profile - provides IT solutions and Web Development
VK Business Profile - provides IT solutions and Web Development
 
Alfresco TTL#157 - Troubleshooting Made Easy: Deciphering Alfresco mTLS Confi...
Alfresco TTL#157 - Troubleshooting Made Easy: Deciphering Alfresco mTLS Confi...Alfresco TTL#157 - Troubleshooting Made Easy: Deciphering Alfresco mTLS Confi...
Alfresco TTL#157 - Troubleshooting Made Easy: Deciphering Alfresco mTLS Confi...
 
Introduction Computer Science - Software Design.pdf
Introduction Computer Science - Software Design.pdfIntroduction Computer Science - Software Design.pdf
Introduction Computer Science - Software Design.pdf
 
Folding Cheat Sheet #4 - fourth in a series
Folding Cheat Sheet #4 - fourth in a seriesFolding Cheat Sheet #4 - fourth in a series
Folding Cheat Sheet #4 - fourth in a series
 
MYjobs Presentation Django-based project
MYjobs Presentation Django-based projectMYjobs Presentation Django-based project
MYjobs Presentation Django-based project
 
Intelligent Home Wi-Fi Solutions | ThinkPalm
Intelligent Home Wi-Fi Solutions | ThinkPalmIntelligent Home Wi-Fi Solutions | ThinkPalm
Intelligent Home Wi-Fi Solutions | ThinkPalm
 
Global Identity Enrolment and Verification Pro Solution - Cizo Technology Ser...
Global Identity Enrolment and Verification Pro Solution - Cizo Technology Ser...Global Identity Enrolment and Verification Pro Solution - Cizo Technology Ser...
Global Identity Enrolment and Verification Pro Solution - Cizo Technology Ser...
 
2.pdf Ejercicios de programación competitiva
2.pdf Ejercicios de programación competitiva2.pdf Ejercicios de programación competitiva
2.pdf Ejercicios de programación competitiva
 
cpct NetworkING BASICS AND NETWORK TOOL.ppt
cpct NetworkING BASICS AND NETWORK TOOL.pptcpct NetworkING BASICS AND NETWORK TOOL.ppt
cpct NetworkING BASICS AND NETWORK TOOL.ppt
 
Advantages of Odoo ERP 17 for Your Business
Advantages of Odoo ERP 17 for Your BusinessAdvantages of Odoo ERP 17 for Your Business
Advantages of Odoo ERP 17 for Your Business
 
SuccessFactors 1H 2024 Release - Sneak-Peek by Deloitte Germany
SuccessFactors 1H 2024 Release - Sneak-Peek by Deloitte GermanySuccessFactors 1H 2024 Release - Sneak-Peek by Deloitte Germany
SuccessFactors 1H 2024 Release - Sneak-Peek by Deloitte Germany
 
Maximizing Efficiency and Profitability with OnePlan’s Professional Service A...
Maximizing Efficiency and Profitability with OnePlan’s Professional Service A...Maximizing Efficiency and Profitability with OnePlan’s Professional Service A...
Maximizing Efficiency and Profitability with OnePlan’s Professional Service A...
 
CRM Contender Series: HubSpot vs. Salesforce
CRM Contender Series: HubSpot vs. SalesforceCRM Contender Series: HubSpot vs. Salesforce
CRM Contender Series: HubSpot vs. Salesforce
 
Tech Tuesday - Mastering Time Management Unlock the Power of OnePlan's Timesh...
Tech Tuesday - Mastering Time Management Unlock the Power of OnePlan's Timesh...Tech Tuesday - Mastering Time Management Unlock the Power of OnePlan's Timesh...
Tech Tuesday - Mastering Time Management Unlock the Power of OnePlan's Timesh...
 
办理学位证(UQ文凭证书)昆士兰大学毕业证成绩单原版一模一样
办理学位证(UQ文凭证书)昆士兰大学毕业证成绩单原版一模一样办理学位证(UQ文凭证书)昆士兰大学毕业证成绩单原版一模一样
办理学位证(UQ文凭证书)昆士兰大学毕业证成绩单原版一模一样
 
Machine Learning Software Engineering Patterns and Their Engineering
Machine Learning Software Engineering Patterns and Their EngineeringMachine Learning Software Engineering Patterns and Their Engineering
Machine Learning Software Engineering Patterns and Their Engineering
 
Exploring Selenium_Appium Frameworks for Seamless Integration with HeadSpin.pdf
Exploring Selenium_Appium Frameworks for Seamless Integration with HeadSpin.pdfExploring Selenium_Appium Frameworks for Seamless Integration with HeadSpin.pdf
Exploring Selenium_Appium Frameworks for Seamless Integration with HeadSpin.pdf
 
What is Fashion PLM and Why Do You Need It
What is Fashion PLM and Why Do You Need ItWhat is Fashion PLM and Why Do You Need It
What is Fashion PLM and Why Do You Need It
 

Shooting the Rapids: Getting the Best from Java 8 Streams

  • 1. Shooting the Rapids: Getting the Best from Java 8 Streams Kirk Pepperdine @kcpeppe Maurice Naftalin @mauricenaftalin
  • 2. About Kirk • Specialises in performance tuning • speaks frequently about performance • author of performance tuning workshop • Co-founder jClarity • performance diagnositic tooling • Java Champion (since 2006)
  • 3. About Kirk • Specialises in performance tuning • speaks frequently about performance • author of performance tuning workshop • Co-founder jClarity • performance diagnositic tooling • Java Champion (since 2006)
  • 9. Agenda • Introduction – lambdas, streams, and a logfile processing problem
  • 10. Agenda • Introduction – lambdas, streams, and a logfile processing problem • Optimizing stream sources
  • 11. Agenda • Introduction – lambdas, streams, and a logfile processing problem • Optimizing stream sources • Tragedy Of The Commons
  • 12. Agenda • Introduction – lambdas, streams, and a logfile processing problem • Optimizing stream sources • Tragedy Of The Commons • Justifying the Overhead
  • 13. Example: Processing GC Logfile ⋮ 2.869: Application time: 1.0001540 seconds 5.342: Application time: 0.0801231 seconds 8.382: Application time: 1.1013574 seconds ⋮
  • 14. Example: Processing GC Logfile ⋮ 2.869: Application time: 1.0001540 seconds 5.342: Application time: 0.0801231 seconds 8.382: Application time: 1.1013574 seconds ⋮
  • 15. sum=2.181635 Example: Processing GC Logfile ⋮ 2.869: Application time: 1.0001540 seconds 5.342: Application time: 0.0801231 seconds 8.382: Application time: 1.1013574 seconds ⋮
  • 16. Example: Processing GC Logfile ⋮ 2.869: Application time: 1.0001540 seconds 5.342: Application time: 0.0801231 seconds 8.382: Application time: 1.1013574 seconds ⋮ DoubleSummaryStatistics {count=3, sum=2.181635, min=0.080123, average=0.727212, max=1.101357}
  • 17. Application time: (d+.d+) Example: Processing GC Logfile ⋮ 2.869: Application time: 1.0001540 seconds 5.342: Application time: 0.0801231 seconds 8.382: Application time: 1.1013574 seconds ⋮ Regex:
  • 18. Application time: (d+.d+) Pattern stoppedTimePattern = Pattern.compile(" "); ⋮ Matcher matcher = stoppedTimePattern.matcher(logRecord); String value = matcher.group(1); Example: Processing GC Logfile
  • 19. Processing GC Logfile: Old School Code Pattern stoppedTimePattern = Pattern.compile("Application time: (d+.d+)"); String logRecord;
 double value = 0;
 while ( ( logRecord = logFileReader.readLine()) != null) {
 Matcher matcher = stoppedTimePattern.matcher(logRecord);
 if ( matcher.find()) {
 value += (Double.parseDouble( matcher.group(1)));
 }
 }
  • 20. Predicate<Matcher> matches = new Predicate<Matcher>() {
 @Override
 public boolean test(Matcher matcher) {
 return matcher.find();
 }
 }; What is a Lambda? matcher matcher.find() matcher matcher.find()
  • 21. Predicate<Matcher> matches = new Predicate<Matcher>() {
 @Override
 public boolean test(Matcher matcher) {
 return matcher.find();
 }
 }; Predicate<Matcher> matches = What is a Lambda? matcher matcher.find() matcher matcher.find()
  • 22. Predicate<Matcher> matches = new Predicate<Matcher>() {
 @Override
 public boolean test(Matcher matcher) {
 return matcher.find();
 }
 }; Predicate<Matcher> matches = What is a Lambda? matcher Predicate<Matcher> matches = matcher.find() matcher matcher.find()
  • 23. Predicate<Matcher> matches = new Predicate<Matcher>() {
 @Override
 public boolean test(Matcher matcher) {
 return matcher.find();
 }
 }; Predicate<Matcher> matches = What is a Lambda? matcherPredicate<Matcher> matches = matcher.find() matcher matcher.find()
  • 24. Predicate<Matcher> matches = new Predicate<Matcher>() {
 @Override
 public boolean test(Matcher matcher) {
 return matcher.find();
 }
 }; Predicate<Matcher> matches = What is a Lambda? matcherPredicate<Matcher> matches = matcher.find() -> matcher matcher.find()
  • 25. Predicate<Matcher> matches = new Predicate<Matcher>() {
 @Override
 public boolean test(Matcher matcher) {
 return matcher.find();
 }
 }; Predicate<Matcher> matches = What is a Lambda? matcherPredicate<Matcher> matches = matcher.find()-> matcher matcher.find()
  • 26. Predicate<Matcher> matches = new Predicate<Matcher>() {
 @Override
 public boolean test(Matcher matcher) {
 return matcher.find();
 }
 }; Predicate<Matcher> matches = What is a Lambda? matcherPredicate<Matcher> matches = A lambda is a function from arguments to result matcher.find()-> matcher matcher.find()
  • 27. Processing Logfile: Stream Code DoubleSummaryStatistics summaryStatistics =
 logFileReader.lines()
 .map(input -> stoppedTimePattern.matcher(input))
 .filter(matcher -> matcher.find())
 .map(matcher -> matcher.group(1))
 .mapToDouble(s -> Double.parseDouble(s))
 .summaryStatistics();

  • 28. Processing Logfile: Stream Code DoubleSummaryStatistics summaryStatistics =
 logFileReader.lines()
 .map(input -> stoppedTimePattern.matcher(input))
 .filter(matcher -> matcher.find())
 .map(matcher -> matcher.group(1))
 .mapToDouble(s -> Double.parseDouble(s))
 .summaryStatistics();
 data source
  • 29. Processing Logfile: Stream Code DoubleSummaryStatistics summaryStatistics =
 logFileReader.lines()
 .map(input -> stoppedTimePattern.matcher(input))
 .filter(matcher -> matcher.find())
 .map(matcher -> matcher.group(1))
 .mapToDouble(s -> Double.parseDouble(s))
 .summaryStatistics();
 start streaming
  • 30. Processing Logfile: Stream Code DoubleSummaryStatistics summaryStatistics =
 logFileReader.lines()
 .map(input -> stoppedTimePattern.matcher(input))
 .filter(matcher -> matcher.find())
 .map(matcher -> matcher.group(1))
 .mapToDouble(s -> Double.parseDouble(s))
 .summaryStatistics();
 map to Matcher
  • 31. Processing Logfile: Stream Code DoubleSummaryStatistics summaryStatistics =
 logFileReader.lines()
 .map(input -> stoppedTimePattern.matcher(input))
 .filter(matcher -> matcher.find())
 .map(matcher -> matcher.group(1))
 .mapToDouble(s -> Double.parseDouble(s))
 .summaryStatistics();
 filter out uninteresting bits
  • 32. Processing Logfile: Stream Code DoubleSummaryStatistics summaryStatistics =
 logFileReader.lines()
 .map(input -> stoppedTimePattern.matcher(input))
 .filter(matcher -> matcher.find())
 .map(matcher -> matcher.group(1))
 .mapToDouble(s -> Double.parseDouble(s))
 .summaryStatistics();
 extract group
  • 33. Processing Logfile: Stream Code DoubleSummaryStatistics summaryStatistics =
 logFileReader.lines()
 .map(input -> stoppedTimePattern.matcher(input))
 .filter(matcher -> matcher.find())
 .map(matcher -> matcher.group(1))
 .mapToDouble(s -> Double.parseDouble(s))
 .summaryStatistics();
 map String to Double
  • 34. Processing Logfile: Stream Code DoubleSummaryStatistics summaryStatistics =
 logFileReader.lines()
 .map(input -> stoppedTimePattern.matcher(input))
 .filter(matcher -> matcher.find())
 .map(matcher -> matcher.group(1))
 .mapToDouble(s -> Double.parseDouble(s))
 .summaryStatistics();
 aggregate results
  • 35. What is a Stream? • A sequence of values • source and intermediate operations set the stream up lazily: Stream<String> groupStream =
 logFileReader.lines()
 .map(stoppedTimePattern::matcher)
 .filter(Matcher::find)
 .map(matcher -> matcher.group(1)) .mapToDouble(Double::parseDouble); Source
  • 36. What is a Stream? • A sequence of values • source and intermediate operations set the stream up lazily: Stream<String> groupStream =
 logFileReader.lines()
 .map(stoppedTimePattern::matcher)
 .filter(Matcher::find)
 .map(matcher -> matcher.group(1)) .mapToDouble(Double::parseDouble); Intermediate Operations
  • 37. What is a Stream? • The terminal operation pulls the values down the stream: SummaryStatistics statistics =
 logFileReader.lines()
 .map(stoppedTimePattern::matcher)
 .filter(Matcher::find)
 .map(matcher -> matcher.group(1)) .mapToDouble(Double::parseDouble) .summaryStatistics();Terminal Operation
  • 38. Visualising Sequential Streams x2x0 x1 x3x0 x1 x2 x3 Source Map Filter Reduction Intermediate Operations Terminal Operation “Values in Motion”
  • 39. Visualising Sequential Streams x2x0 x1 x3x1 x2 x3 ✔ Source Map Filter Reduction Intermediate Operations Terminal Operation “Values in Motion”
  • 40. Visualising Sequential Streams x2x0 x1 x3 x1x2 x3 ❌✔ Source Map Filter Reduction Intermediate Operations Terminal Operation “Values in Motion”
  • 41. Visualising Sequential Streams x2x0 x1 x3 x1x2x3 ❌✔ Source Map Filter Reduction Intermediate Operations Terminal Operation “Values in Motion”
  • 42. Old School: 80200ms Sequential: 25800ms (>9m lines, MacBook Pro, Haswell i7, 4 cores, hyperthreaded) Stream code is faster because operations are fused How Does That Perform?
  • 43. Can We Do Better? Parallel streams make use of multiple cores • split the data into segments • each segment processed by its own thread - on its own core – if possible
  • 44. Splitting the Data Implemented by a Spliterator:
  • 45. Splitting the Data Implemented by a Spliterator:
  • 46. Splitting the Data Implemented by a Spliterator:
  • 47. Splitting the Data Implemented by a Spliterator:
  • 48. Splitting the Data Implemented by a Spliterator:
  • 49. Splitting the Data Implemented by a Spliterator:
  • 50. Splitting the Data Implemented by a Spliterator:
  • 51. Splitting the Data Implemented by a Spliterator:
  • 52. Splitting the Data Implemented by a Spliterator:
  • 56. x2 Visualizing Parallel Streams x1 y3 x0 x1 x3 ✔ ❌
  • 57. Stream Code DoubleSummaryStatistics summaryStatistics =
 logFileReader.lines().parallel()
 .map(stoppedTimePattern::matcher)
 .filter(Matcher::find)
 .map(matcher -> matcher.group(1))
 .mapToDouble(Double::parseDouble)
 .summaryStatistics();
  • 58. Results of Going Parallel: • No benefit from using parallel streams while streaming data
  • 60. Agenda • Introduction – lambdas, streams, and a logfile processing problem
  • 61. Agenda • Introduction – lambdas, streams, and a logfile processing problem • Optimizing stream sources
  • 62. Agenda • Introduction – lambdas, streams, and a logfile processing problem • Optimizing stream sources • Tragedy Of The Commons
  • 63. Agenda • Introduction – lambdas, streams, and a logfile processing problem • Optimizing stream sources • Tragedy Of The Commons • Justifying the Overhead
  • 65. • Some sources split much worse than others – LinkedList vs. ArrayList Poorly Splitting Sources
  • 66. • Some sources split much worse than others – LinkedList vs. ArrayList • Streaming I/O is bad. – kills the advantage of going parallel Poorly Splitting Sources
  • 67. • Some sources split much worse than others – LinkedList vs. ArrayList • Streaming I/O is bad. – kills the advantage of going parallel Poorly Splitting Sources
  • 68. Streaming I/O Bottleneck x2x0 x1 x3x0 x1 x2 x3
  • 70. 5.342: … nds LineSpliterator 2.869:Applicati … seconds n 8.382: … nds 9.337:App … ndsn n n spliterator coverage
  • 71. 5.342: … nds LineSpliterator 2.869:Applicati … seconds n 8.382: … nds 9.337:App … ndsn n n spliterator coverage MappedByteBuffer
  • 72. 5.342: … nds LineSpliterator 2.869:Applicati … seconds n 8.382: … nds 9.337:App … ndsn n n spliterator coverage MappedByteBuffer mid
  • 73. 5.342: … nds LineSpliterator 2.869:Applicati … seconds n 8.382: … nds 9.337:App … ndsn n n spliterator coverage MappedByteBuffer mid
  • 74. 5.342: … nds LineSpliterator 2.869:Applicati … seconds n 8.382: … nds 9.337:App … ndsn n n spliterator coveragenew spliterator coverage MappedByteBuffer mid
  • 75. 5.342: … nds LineSpliterator 2.869:Applicati … seconds n 8.382: … nds 9.337:App … ndsn n n spliterator coveragenew spliterator coverage MappedByteBuffer mid Included in JDK9 as FileChannelLinesSpliterator
  • 76. StreamingIO: 56s Spliterator: 88s (>9m lines, MacBook Pro, Haswell i7, 4 cores, hyperthreaded) Stream code is faster because operations are fused LineSpliterator – results
  • 77. When to Use Parallel Streams?
  • 78. When to Use Parallel Streams? • Task must be recursively decomposable – subtasks for each data segment must be independent
  • 79. When to Use Parallel Streams? • Task must be recursively decomposable – subtasks for each data segment must be independent • Source must be well-splitting
  • 80. When to Use Parallel Streams? • Task must be recursively decomposable – subtasks for each data segment must be independent • Source must be well-splitting • Enough hardware to support allVM needs – there may be other business afoot
  • 81. When to Use Parallel Streams? • Task must be recursively decomposable – subtasks for each data segment must be independent • Source must be well-splitting • Enough hardware to support allVM needs – there may be other business afoot • Overhead of splitting must be justified – intermediate operations need to be expensive – and CPU-bound
  • 82. When to Use Parallel Streams? • Task must be recursively decomposable – subtasks for each data segment must be independent • Source must be well-splitting • Enough hardware to support allVM needs – there may be other business afoot • Overhead of splitting must be justified – intermediate operations need to be expensive – and CPU-bound http://gee.cs.oswego.edu/dl/html/StreamParallelGuidance.html
  • 84. Agenda • Introduction – lambdas, streams, and a logfile processing problem
  • 85. Agenda • Introduction – lambdas, streams, and a logfile processing problem • Optimizing stream sources
  • 86. Agenda • Introduction – lambdas, streams, and a logfile processing problem • Optimizing stream sources • Tragedy Of The Commons
  • 87. Agenda • Introduction – lambdas, streams, and a logfile processing problem • Optimizing stream sources • Tragedy Of The Commons • Justifying the Overhead
  • 88. Tragedy of the Commons
  • 89. Tragedy of the Commons You have a finite amount of hardware – it might be in your best interest to grab it all – but if everyone behaves the same way…
  • 91. Agenda • Introduction – lambdas, streams, and a logfile processing problem
  • 92. Agenda • Introduction – lambdas, streams, and a logfile processing problem • Optimizing stream sources
  • 93. Agenda • Introduction – lambdas, streams, and a logfile processing problem • Optimizing stream sources • Tragedy Of The Commons
  • 94. Agenda • Introduction – lambdas, streams, and a logfile processing problem • Optimizing stream sources • Tragedy Of The Commons • Justifying the Overhead
  • 95. Justifying the Overhead CPNQ performance model: C - number of submitters P - number of CPUs N - number of elements Q - cost of the operation
  • 96. Justifying the Overhead Need to amortize setup costs – N*Q needs to be large – Q can often only be estimated – N often should be >10,000 elements If P is the number of processors, the formula assumes that intermediate tasks are CPU bound
  • 97. Don’t Have Too Many Threads! • Too many threads cause frequent handoffs • It costs ~80,000 cycles to handoff data between threads • You can do a lot of processing in 80,000 cycles!
  • 99. Fork/Join • Parallel streams implemented by Fork/Join framework • added in Java 7, but difficult to code • parallel streams are more usable
  • 100. Fork/Join • Parallel streams implemented by Fork/Join framework • added in Java 7, but difficult to code • parallel streams are more usable
  • 101. Fork/Join • Parallel streams implemented by Fork/Join framework • added in Java 7, but difficult to code • parallel streams are more usable • Each segment of data is submitted as a ForkJoinTask • ForkJoinTask.invoke() spawns a new task • ForkJoinTask.join() retrieves the result
  • 102. Fork/Join • Parallel streams implemented by Fork/Join framework • added in Java 7, but difficult to code • parallel streams are more usable • Each segment of data is submitted as a ForkJoinTask • ForkJoinTask.invoke() spawns a new task • ForkJoinTask.join() retrieves the result • How Fork/Join works and performs is important to your latency picture
  • 103. Common Fork/Join Pool Fork/Join by default uses a common thread pool - default number of worker threads == number of logical cores - 1 - (submitting thread is pressed into service) - can configure the pool via system properties: - or create our own pool… java.util.concurrent.ForkJoinPool.common.parallelism
 java.util.concurrent.ForkJoinPool.common.threadFactory
 java.util.concurrent.ForkJoinPool.common.exceptionHandler
  • 104. Custom Fork/Join Pool When used inside a ForkJoinPool, the ForkJoinTask.fork() method uses the current pool: ForkJoinPool ourOwnPool = new ForkJoinPool(10); ourOwnPool.invoke( () -> stream.parallel(). ⋮
  • 105. Don’t Have Too Few Threads! • Fork/Join pool uses a work queue • If tasks are CPU bound, no use increasing the size of the thread pool • But if not CPU bound, they are sitting in queue accumulating dead time • Can make thread pool bigger to reduce dead time • Little’s Law tells us Number of tasks in the system =
 Arrival rate * Average service time
  • 106. Little’s Law Example System receives 400 Txs and it takes 100ms to clear a request - Number of tasks in system = 0.100 * 400 = 40 On an 8 core machine with a CPU bound task - implies 32 tasks are sitting in queue accumulating dead time - Average response time 600 ms of which 500ms is dead time - ~83% of service time is in waiting
  • 107. public final V invoke() { ForkJoinPool.common.getMonitor().submitTask(this); int s; if ((s = doInvoke() & DONE_MASK) != NORMAL) reportException(s); ForkJoinPool.common.getMonitor().retireTask(this); return getRawResult(); } ForkJoinPool Observability ForkJoinPool comes with no visibility - need to instrument ForkJoinTask.invoke() – gather data from ForkJoinPool to feed into Little’s Law
  • 108. Conclusions Sequential stream performance comparable to imperative code Going parallel is worthwhile IF - task is suitable - data source is suitable - environment is suitable Need to monitor JDK to understanding bottlenecks - Fork/Join pool is not well instrumented