Trisha Gee (@trisha_gee) Developer & Technical Advocate, JetBrains
Refactoring to Java 8 Trisha Gee (@trisha_gee) Developer & - - PowerPoint PPT Presentation
Refactoring to Java 8 Trisha Gee (@trisha_gee) Developer & - - PowerPoint PPT Presentation
Refactoring to Java 8 Trisha Gee (@trisha_gee) Developer & Technical Advocate, JetBrains Why Java 8? Its Faster Performance Improvements in Common Data Structures Fork/Join Speed Improvements Changes to Support Concurrency
Why Java 8?
It’s Faster
- Performance Improvements in Common Data
Structures
- Fork/Join Speed Improvements
- Changes to Support Concurrency
- …and more
http://bit.ly/refJ8
Easy to Parallelize
Fewer Lines of Code
New Solutions to Problems
Minimizes Errors
Safety Check
Test Coverage
Performance Tests
Decide on the Goals
Limit the Scope
Morphia
https://github.com/mongodb/morphia
Refactoring!
Lambda Expressions
Automatic Refactoring
- Predicate
- Comparator
- Runnable
- etc…
Abstract classes
Advanced Search
Collections & Streams API
Automatic Refactoring
- For loop to collect
- For loop to forEach
- …with and without Streams
Manual Refactoring
Optional
But what about performance?
Lambdas
20 40 60 80 100 120 140 160 180
Ops/ms
Anonymous Inner Classes vs Lambdas
Anonymous Inner Class Lambda
http://www.oracle.com/technetwork/java/jvmls2013kuksen-2014088.pdf
2 4 6 8 10 12 14 16 18 20
single thread max threads nsec/op
Performance of Capture
anonymous(static) anonymous(non-static) lambda
50,000 100,000 150,000 200,000 250,000 300,000 350,000 400,000 450,000 500,000
Constant message Variable message Ops/ms
Logging Performance
Direct call Lambda
Streams vs Iteration
1 2 3 4 5 6 7 8 9
Ops/ms
Iterator vs Stream (1000 elements)
for loop forEach()
1000 2000 3000 4000 5000 6000 7000
1 10 100 1000 Ops/ms
IterHelper
- riginal
simplified refactored
1 2 3 4 5 6 7 8 9
1000 10000 100000 Ops/ms
IterHelper
- riginal
simplified refactored
BasicDAO – map & collect
5000 10000 15000 20000 25000
1 10 100 1000
Ops/msBasicDAO
- riginal
simplified refactored
DuplicatedAttributeNames – filter, map & collect
200 400 600 800 1000 1200
Ops/ms
DuplicatedAttributeNames
- riginal
refactored
EntityScanner– forEach
0.01 0.02 0.03 0.04 0.05 0.06
Ops/ms
EntityScanner
- riginal
refactored
DatastoreImpl – filter & forEach
0.1 0.2 0.3 0.4 0.5 0.6 0.7
Ops/ms
DatastoreImpl
- riginal
refactored
MappingValidator – single stream operation
100 200 300 400 500 600 700 800 900
EntityWithOneError EntityWith10Errors EntityWith20Errors Ops/ms
MappingValidator
- riginal
refactored
QueryImpl – multiple operations
500 1000 1500 2000 2500 3000 3500
Ops/ms
QueryImpl
- riginal
simplified refactored
Going parallel
0.1 0.2 0.3 0.4 0.5 0.6 0.7 0.8 0.9 Serial Parallel Time Taken (seconds)
map()
MacBook Surface
20 40 60 80 100 120 140 160 Serial Parallel Time Taken (millis)
findAny()
MacBook Surface
Optional
50,000 100,000 150,000 200,000 250,000 300,000 350,000
Value not null Value null Ops/ms
Compare Constant Field Value with Null
Null check Optional
50,000 100,000 150,000 200,000 250,000 300,000
Value not null Value null Ops/ms
Compare Variable Field Value with Null
Null check Optional
Summary
Sometimes new idioms decrease clutter
…but sometimes they don’t
Sometimes the new features improve performance
20 40 60 80 100 120 140 160 180
Ops/ms
Anonymous Inner Classes vs Lambdas
Anonymous Inner Class Lambda
…and sometimes they don’t
200 400 600 800 1000 1200
Ops/ms
DuplicatedAttributeNames
- riginal
refactored
Sometimes a new feature makes life easier
…sometimes not so much
Some refactoring can safely be done automatically
…often you need a human brain
Conclusion
Should you migrate your code to Java 8?
It Depends
Always remember what your goal is
And compare results to it
Understand what may impact performance
And if in doubt, measure
Code may magically improve
Or you may expose areas for improvement
Your tools can help you
But you need to apply your brain too
http://bit.ly/refJ8
@trisha_gee