Refactoring to Java 8 Trisha Gee (@trisha_gee) Developer & Technical Advocate, JetBrains
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
Anonymous Inner Classes vs Lambdas 180 160 140 120 100 Ops/ms 80 60 40 20 0 Anonymous Inner Class Lambda
Performance of Capture 20 18 16 14 12 nsec/op 10 8 6 4 2 0 single thread max threads anonymous(static) anonymous(non-static) lambda http://www.oracle.com/technetwork/java/jvmls2013kuksen-2014088.pdf
Logging Performance 500,000 450,000 400,000 350,000 300,000 Ops/ms 250,000 200,000 150,000 100,000 50,000 0 Constant message Variable message Direct call Lambda
Streams vs Iteration
Iterator vs Stream (1000 elements) 9 8 7 6 5 Ops/ms 4 3 2 1 0 for loop forEach()
IterHelper 7000 6000 5000 4000 Ops/ms 3000 2000 1000 0 1 10 100 1000 original simplified refactored
IterHelper 9 8 7 6 5 Ops/ms 4 3 2 1 0 1000 10000 100000 original simplified refactored
BasicDAO – map & collect
BasicDAO 25000 20000 15000 Ops/ms 10000 5000 0 1 10 100 1000 original simplified refactored
DuplicatedAttributeNames – filter, map & collect
DuplicatedAttributeNames 1200 1000 800 Ops/ms 600 400 200 0 original refactored
EntityScanner – forEach
EntityScanner 0.06 0.05 0.04 Ops/ms 0.03 0.02 0.01 0 original refactored
DatastoreImpl – filter & forEach
DatastoreImpl 0.7 0.6 0.5 0.4 Ops/ms 0.3 0.2 0.1 0 original refactored
MappingValidator – single stream operation
MappingValidator 900 800 700 600 Ops/ms 500 400 300 200 100 0 EntityWithOneError EntityWith10Errors EntityWith20Errors original refactored
QueryImpl – multiple operations
QueryImpl 3500 3000 2500 2000 Ops/ms 1500 1000 500 0 original simplified refactored
Going parallel
map() 0.9 0.8 Time Taken (seconds) 0.7 0.6 0.5 0.4 0.3 0.2 0.1 0 Serial Parallel MacBook Surface
findAny() 160 140 Time Taken (millis) 120 100 80 60 40 20 0 Serial Parallel MacBook Surface
Optional
Compare Constant Field Value with Null 350,000 300,000 250,000 200,000 Ops/ms 150,000 100,000 50,000 0 Value not null Value null Null check Optional
Compare Variable Field Value with Null 300,000 250,000 200,000 Ops/ms 150,000 100,000 50,000 0 Value not null Value null Null check Optional
Summary
Sometimes new idioms decrease clutter
…but sometimes they don’t
Sometimes the new features improve performance
Anonymous Inner Classes vs Lambdas 180 160 140 120 100 Ops/ms 80 60 40 20 0 Anonymous Inner Class Lambda
…and sometimes they don’t
DuplicatedAttributeNames 1200 1000 800 Ops/ms 600 400 200 0 original 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
Recommend
More recommend