SLIDE 1 Migrating Speedment to Java 9
Dan Lawesson , @dan_lawesson
CSO, Speedment, Inc
SLIDE 2
About Us
SLIDE 3 About Us
Dan Lawesson, PhD
- AI, model-based diagnosis
- CSO with S as in Science
- 20 years of Java experience
- Previous lives: telecom and
automotive IoT
SLIDE 4 About Us
Dan Lawesson, PhD
- AI, model-based diagnosis
- CSO with S as in Science
- 20 years of Java experience
- Previous lives: telecom and
automotive IoT
Spire
- Speedment Open Source mascot
- Lives on GitHub
- 2 years of mascot experience
SLIDE 5
Outline
SLIDE 6 Outline
- Speedment
- Jigsaw
- Jigsawing Speedment
SLIDE 7
Speedment
SLIDE 8
Speedment
Speedment is
SLIDE 9 Speedment
Speedment is
SLIDE 10 Speedment
Speedment is
- a Streams API ORM
- using in-JVM memory acceleration
SLIDE 11 Speedment
Speedment is
- a Streams API ORM
- using in-JVM memory acceleration
- and Code Generation,
SLIDE 12 Speedment
Speedment is
- a Streams API ORM
- using in-JVM memory acceleration
- and Code Generation,
- with modular design
SLIDE 13 Speedment
Speedment is
- a Streams API ORM
- using in-JVM memory acceleration
- and Code Generation,
- with modular design
Oracle Java Magazine May-June pages 34-40
SLIDE 14 Speedment
Speedment is
- a Streams API ORM
- using in-JVM memory acceleration
- and Code Generation,
- with modular design
Oracle Java Magazine May-June pages 34-40
SLIDE 15
SLIDE 16
Compile-time Code Generation Tool
SLIDE 17
Compile-time Code Generation Tool
SLIDE 18
SLIDE 19
Querying the Database using Streams
SLIDE 20 Querying the Database using Streams
- Queries are expressed using the
standard Java 8 Stream API
SLIDE 21 Querying the Database using Streams
- Queries are expressed using the
standard Java 8 Stream API
- Streams are analyzed to produce
high-performance queries
SLIDE 22 Expressing Queries as Streams
customers.stream() .filter(Customer.REGION.equal(Region.NORTH_AMERICA)) .filter(Customer.REGISTERED.greaterOrEqual(startOfYear)) .count();
SLIDE 23 Expressing Queries as Streams
customers.stream() .filter(Customer.REGION.equal(Region.NORTH_AMERICA)) .filter(Customer.REGISTERED.greaterOrEqual(startOfYear)) .count(); Standard Stream API
SLIDE 24 Expressing Queries as Streams
customers.stream() .filter(Customer.REGION.equal(Region.NORTH_AMERICA)) .filter(Customer.REGISTERED.greaterOrEqual(startOfYear)) .count(); Standard Stream API Full Type-Safety
SLIDE 25 Expressing Queries as Streams
customers.stream() .filter(Customer.REGION.equal(Region.NORTH_AMERICA)) .filter(Customer.REGISTERED.greaterOrEqual(startOfYear)) .count(); Standard Stream API Generated Enum Constants Full Type-Safety
SLIDE 26 Expressing Queries as Streams
customers.stream() .filter(Customer.REGION.equal(Region.NORTH_AMERICA)) .filter(Customer.REGISTERED.greaterOrEqual(startOfYear)) .count(); Standard Stream API Generated Enum Constants Only 1 value is loaded from DB Full Type-Safety
SLIDE 27 Expressing Queries as Streams
customers.stream() .filter(Customer.REGION.equal(Region.NORTH_AMERICA)) .filter(Customer.REGISTERED.greaterOrEqual(startOfYear)) .count(); Standard Stream API Generated Enum Constants Only 1 value is loaded from DB Full Type-Safety
SELECT COUNT('id') FROM 'customer' WHERE 'customer'.'region' = ‘North America’ AND 'customer'.'registered' >= ‘2016-01-01’;
SLIDE 28 Querying the Database using Streams
SELECT * FROM 'customer' REGION.equal(NORTH_AMERICA) REGISTERED.greaterOrEqual(2016-01-01) count() Source Filter Filter Term. Pipeline
SLIDE 29 Querying the Database using Streams
SELECT * FROM 'customer' WHERE 'customer'.'region' = ‘North America’ REGION.equal(NORTH_AMERICA) REGISTERED.greaterOrEqual(2016-01-01) count() Source Filter Filter Term. Pipeline
SLIDE 30 Querying the Database using Streams
SELECT * FROM 'customer' WHERE 'customer'.'region' = ‘North America’ AND 'customer'.'registered' >= ‘2016-01-01’; REGISTERED.greaterOrEqual(2016-01-01) count() Source Filter Term. Pipeline
SLIDE 31 Querying the Database using Streams
SELECT COUNT('id') FROM 'customer' WHERE 'customer'.'region' = ‘North America’ AND 'customer'.'registered' >= ‘2016-01-01’; count() Source Term. Pipeline
SLIDE 32 Querying the Database using Streams
SELECT COUNT('id') FROM 'customer' WHERE 'customer'.'region' = ‘North America’ AND 'customer'.'registered' >= ‘2016-01-01’; Source Pipeline
SLIDE 33 Expressing Queries as Streams
// Gets the second page of customers in North America // sorted by name in the form of a JSON array
SLIDE 34 Expressing Queries as Streams
// Gets the second page of customers in North America // sorted by name in the form of a JSON array customers.stream() .filter(REGION.equal(Region.NORTH_AMERICA)) .sorted(NAME.comparator()) .skip(10) .limit(10) // JVM from here… .collect(toJson(encode.allOf(customers))) [ {”id”:11, ”name”: …}, {…}, … ]
SLIDE 35 Parallelism as Expected for a Stream
// Supports parallelism on custom executors // with full control of thread work item layout
SLIDE 36 Parallelism as Expected for a Stream
// Supports parallelism on custom executors // with full control of thread work item layout customers.stream() .parallel() .filter(REGION.equal(Region.NORTH_AMERICA)) .forEach(expensiveOperatation());
SLIDE 37
Querying
Optional<Hare> oldHare = hares.stream() .filter(Hare.AGE.greaterThan(5)) .findAny();
SLIDE 38 Querying
Optional<Hare> oldHare = hares.stream() .filter(Hare.AGE.greaterThan(5)) .findAny();
Predicate Builder
SLIDE 39 Querying
Optional<Hare> oldHare = hares.stream() .filter(Hare.AGE.greaterThan(5)) .findAny();
Predicate Builder
SELECT id, name, color, age FROM hare WHERE (age > 5) LIMIT 1;
SLIDE 40
Entities are Linked
// Find the owner of the orange carrot Optional<Hare> hare = carrots.stream() .filter(Carrot.NAME.equal("Orange")) .map(hares.finderBy(Carrot.OWNER)) .findAny(); // Find one carrot owned by Harry // Carrot is a foreign key table Optional<Carrot> carrot = hares.stream() .filter(Hare.NAME.equal("Harry")) .flatMap(carrots.finderBackwardsBy(Carrot.OWNER)) .findAny();
SLIDE 41
Joins
Map<Hare, List<Carrot>> join = carrots.stream() .collect( groupingBy(hares.finderBy(Carrot.OWNER)) );
SLIDE 42 Joins
Map<Hare, List<Carrot>> join = carrots.stream() .collect( groupingBy(hares.finderBy(Carrot.OWNER)) );
Standard Java 8
SLIDE 43 Joins
Map<Hare, List<Carrot>> join = carrots.stream() .collect( groupingBy(hares.finderBy(Carrot.OWNER)) );
Standard Java 8
SLIDE 44
Imperative vs Declarative
SLIDE 45
Imperative vs Declarative
SQL describes what rather than how
SLIDE 46
Imperative vs Declarative
SQL describes what rather than how database engine figures out the how
SLIDE 47
Imperative vs Declarative
SQL describes what rather than how database engine figures out the how Streams are also declarative - a result is described
SLIDE 48
Imperative vs Declarative
SQL describes what rather than how database engine figures out the how Streams are also declarative - a result is described framework takes pipeline as input and determines the how
SLIDE 49
Typical ORM + Java Streams Application
SLIDE 50
Typical ORM + Java Streams Application
Explicit SQL + Java Stream is an imperative two step program:
SLIDE 51 Typical ORM + Java Streams Application
Explicit SQL + Java Stream is an imperative two step program:
- 1. Compute Result Set SELECT x FROM y WHERE z
SLIDE 52 Typical ORM + Java Streams Application
Explicit SQL + Java Stream is an imperative two step program:
- 1. Compute Result Set SELECT x FROM y WHERE z
- 2. Stream over Result Set rs.stream().filter…
SLIDE 53
Speedment - Breaking the Language Barrier
SLIDE 54
Speedment - Breaking the Language Barrier
Java Stream expressing both database and JVM operations ->
SLIDE 55
Speedment - Breaking the Language Barrier
Java Stream expressing both database and JVM operations -> the program is declarative,
SLIDE 56
Speedment - Breaking the Language Barrier
Java Stream expressing both database and JVM operations -> the program is declarative, the runtime determines the DB-JVM work split.
SLIDE 57
Speedment - Fully Declarative DB Applications
SLIDE 58
Speedment - Fully Declarative DB Applications
Fully declarative ->
SLIDE 59
Speedment - Fully Declarative DB Applications
Fully declarative -> Speedment Enterprise: add in-memory-acceleration
SLIDE 60
Speedment - Fully Declarative DB Applications
Fully declarative -> Speedment Enterprise: add in-memory-acceleration without changing anything in the stream application.
SLIDE 61
Jigsaw
SLIDE 62
Jigsaw
SLIDE 63 Jigsaw
- Modules - an abstraction on top of packages
- Strong Encapsulation
- Reliable Configuration
SLIDE 64 Jigsaw
- Modules - an abstraction on top of packages
- Strong Encapsulation
- Reliable Configuration
SLIDE 65
SLIDE 66
Split Packages
Reliable configuration - a package may only belong to one module
SLIDE 67
Split Packages
Reliable configuration - a package may only belong to one module
SLIDE 68
Split Packages
Reliable configuration - a package may only belong to one module
SLIDE 69
Split Packages
Reliable configuration - a package may only belong to one module
X
SLIDE 70
SLIDE 71
Automatic Modules
SLIDE 72 Automatic Modules
- Smooth transition to Java 9
SLIDE 73 Automatic Modules
- Smooth transition to Java 9
- Move the Java 8 JAR from class path to module path
SLIDE 74 Automatic Modules
- Smooth transition to Java 9
- Move the Java 8 JAR from class path to module path
- The JAR automatically becomes a module
SLIDE 75
SLIDE 76 Automatic modules vs split packages
- Maven puts dependencies on the module path
SLIDE 77 Automatic modules vs split packages
- Maven puts dependencies on the module path
- Java 8 to 9 portability -> automatic modules
SLIDE 78 Automatic modules vs split packages
- Maven puts dependencies on the module path
- Java 8 to 9 portability -> automatic modules
- Automatic modules give split packages
SLIDE 79 Automatic modules vs split packages
- Maven puts dependencies on the module path
- Java 8 to 9 portability -> automatic modules
- Automatic modules give split packages
- But reliable configuration means no split packages
SLIDE 80 Automatic modules vs split packages
- Maven puts dependencies on the module path
- Java 8 to 9 portability -> automatic modules
- Automatic modules give split packages
- But reliable configuration means no split packages
⊥
SLIDE 81
Some Other Jigsaw Controversies
SLIDE 82 Some Other Jigsaw Controversies
- Works for JDK != works for applications
- Restricts current application domain use cases
SLIDE 83 Some Other Jigsaw Controversies
- Works for JDK != works for applications
- Restricts current application domain use cases
- sun.misc.Unsafe
- ”Should not be used” vs ”A key for Java real-world success”
SLIDE 84 Some Other Jigsaw Controversies
- Works for JDK != works for applications
- Restricts current application domain use cases
- sun.misc.Unsafe
- ”Should not be used” vs ”A key for Java real-world success”
- Fundamentally different compared to e.g. OSGi
- lazy loading, dynamic package adding, split packages
SLIDE 85
Jigsawing the Java 8 Application
SLIDE 86 Jigsawing the Java 8 Application
- Run Java 8 under Java 9 is super easy
SLIDE 87 Jigsawing the Java 8 Application
- Run Java 8 under Java 9 is super easy
java –cp <…> –jar app.jar
SLIDE 88 Jigsawing the Java 8 Application
- Run Java 8 under Java 9 is super easy
java –cp <…> –jar app.jar
- The challenge is to move from cp to mp
SLIDE 89
Inter module dependencies
SLIDE 90
Inter module dependencies
Dependencies explicitly given in module-info.java
SLIDE 91 Inter module dependencies
Dependencies explicitly given in module-info.java
module com.speedment.common {
requires com.foo.bar; // a module we depend on exports com.speedment.common.invariant; // a package we expose to the user }
SLIDE 92
A Straight-Forward Modularization Approach
class path module path
SLIDE 93 A Straight-Forward Modularization Approach
- 1. All JARs on class path <all jars>
class path module path
SLIDE 94 A Straight-Forward Modularization Approach
- 1. All JARs on class path <all jars>
- 2. App as a monolithic module <all deps> myapp.jar
class path module path
SLIDE 95 A Straight-Forward Modularization Approach
- 1. All JARs on class path <all jars>
- 2. App as a monolithic module <all deps> myapp.jar
- 3. Declare dependencies
class path module path
SLIDE 96 A Straight-Forward Modularization Approach
- 1. All JARs on class path <all jars>
- 2. App as a monolithic module <all deps> myapp.jar
- 3. Declare dependencies
- 4. Move some JARs from cp to mp <deps> ->
class path module path
SLIDE 97 A Straight-Forward Modularization Approach
- 1. All JARs on class path <all jars>
- 2. App as a monolithic module <all deps> myapp.jar
- 3. Declare dependencies
- 4. Move some JARs from cp to mp <deps> ->
- 5. Modularize app
class path module path
SLIDE 98
The Speedment Java 8 Modules
SLIDE 99
The Speedment Java 8 Modules
Speedment pom.xml
SLIDE 100 The Speedment Java 8 Modules
Speedment pom.xml
<modules> <module>common-parent</module> <module>runtime-parent</module> <module>generator-parent</module> <module>tool-parent</module> <module>build-parent</module> <module>plugin-parent</module> <module>connector-parent</module> <module>archetype-parent</module> <module>example-parent</module> </modules>
SLIDE 101
The Modules of the Speedment common Module
SLIDE 102
The Modules of the Speedment common Module
Speedment common/pom.xml
SLIDE 103 The Modules of the Speedment common Module
Speedment common/pom.xml
<modules> <module>invariant</module> <module>function</module> <module>json</module> <module>tuple</module> <module>logger</module> <module>codegen</module> <module>codegenxml</module> <module>injector</module> <module>rest</module> <module>lazy</module> <module>mapstream</module> <module>mutablestream</module> <module>singletonstream</module> <module>common-all</module> <module>annotation</module> <module>benchmark</module> <module>combinatorics</module> <module>collection</module> </modules>
SLIDE 104
Automatic Jigsawing Script Outline
SLIDE 105 Automatic Jigsawing Script Outline
- Create separate directories for the modules
SLIDE 106 Automatic Jigsawing Script Outline
- Create separate directories for the modules
- Move source code packages to respective modules
SLIDE 107 Automatic Jigsawing Script Outline
- Create separate directories for the modules
- Move source code packages to respective modules
- Add empty module-info.java
SLIDE 108 Automatic Jigsawing Script Outline
- Create separate directories for the modules
- Move source code packages to respective modules
- Add empty module-info.java
- Loop:
- 1. Compile
SLIDE 109 Automatic Jigsawing Script Outline
- Create separate directories for the modules
- Move source code packages to respective modules
- Add empty module-info.java
- Loop:
- 1. Compile
- 2. Parse and fix errors
SLIDE 110 Automatic Jigsawing Script Outline
- Create separate directories for the modules
- Move source code packages to respective modules
- Add empty module-info.java
- Loop:
- 1. Compile
- 2. Parse and fix errors
- 3. git add
- 4. git commit
SLIDE 111
Automatic Jigsawing - add requires
SLIDE 112
Automatic Jigsawing - add requires
Missing Speedment internal dependency
\[ERROR\].*\(package (.*) is declared in module (.*), but module com.speedment.(.*)\.(.*) does not read it\) Fix: module com.speedment.X { + requires com.speedment.Y; }
SLIDE 113
Automatic Jigsawing - add exports
SLIDE 114
Automatic Jigsawing - add exports
Missing Speedment internal visibility
\[ERROR\].*\(package com.speedment.(.*)\.(.*) is declared in module com.speedment.(.*)\.(.*), which does not export it\) Fix: module com.speedment.Y { + exports com.speedment.X; }
SLIDE 115
Automatic Jigsawing - patch (ab)use of JDK API
SLIDE 116 Automatic Jigsawing - patch (ab)use of JDK API
Speedment usage of non-public JDK API
\[ERROR\].*\(package (.*) is declared in module (.*), which does not export it to module com.speedment.(.*)\.(.*)\) Temporary workaround: add exports in the pom file
<artifactId>maven-compiler-plugin</artifactId> + <configuration> + <compilerArgs> + <arg>—add-exports</arg><arg>java.base/sun.nio.ch=com.speedment.… + </compilerArgs> + </configuration>
SLIDE 117
Automatic Jigsawing - remove OSGi bundling
SLIDE 118 Automatic Jigsawing - remove OSGi bundling
Maven does not currently coexist well with OSGi bundling and Jigsaw
\[ERROR\].*Manifest com\.speedment\.([^:]*)\:([^:]*)\:[^:]*\:.* \: Invalid class file module-info\.class \ (java\.lang\.ArrayIndexOutOfBoundsException\: 19\)
Temporary workaround: comment out the bundling
- <packaging>bundle</packaging>
+ <packaging>jar</packaging> … <plugins> + <!-- <plugin> <groupId>org.apache.felix</groupId> …
SLIDE 119
Speedment Open Source - the Easy Case
SLIDE 120 Speedment Open Source - the Easy Case
- No usage of sun.misc.Unsafe
SLIDE 121 Speedment Open Source - the Easy Case
- No usage of sun.misc.Unsafe
- No third party dependencies
SLIDE 122 Speedment Open Source - the Easy Case
- No usage of sun.misc.Unsafe
- No third party dependencies
- JDK dependencies on module path - no automatic modules
SLIDE 123 Speedment Open Source - the Easy Case
- No usage of sun.misc.Unsafe
- No third party dependencies
- JDK dependencies on module path - no automatic modules
- Automatic script creates workarounds that will need revisiting
SLIDE 124 Speedment Open Source - the Easy Case
- No usage of sun.misc.Unsafe
- No third party dependencies
- JDK dependencies on module path - no automatic modules
- Automatic script creates workarounds that will need revisiting
- No reflection
SLIDE 125
No Reflection in Speedment
SLIDE 126 No Reflection in Speedment
- O/R mapping -> reflection
SLIDE 127 No Reflection in Speedment
- O/R mapping -> reflection
- instantiate user code
SLIDE 128 No Reflection in Speedment
- O/R mapping -> reflection
- instantiate user code
- Code Generation to the Rescue!
SLIDE 129
Speedment Enterprise - a Jigsaw Puzzle
SLIDE 130
Speedment Enterprise - a Jigsaw Puzzle
Uses sun.misc.Unsafe
SLIDE 131 Speedment Enterprise - a Jigsaw Puzzle
Uses sun.misc.Unsafe
- DirectBuffer.cleaner() - for predictable cleanup
SLIDE 132 Speedment Enterprise - a Jigsaw Puzzle
Uses sun.misc.Unsafe
- DirectBuffer.cleaner() - for predictable cleanup
- DirectBuffer.address() - for efficient off-heap byte arrays
SLIDE 133 Speedment Enterprise - a Jigsaw Puzzle
Uses sun.misc.Unsafe
- DirectBuffer.cleaner() - for predictable cleanup
- DirectBuffer.address() - for efficient off-heap byte arrays
Third party dependencies
SLIDE 134 Speedment Enterprise - a Jigsaw Puzzle
Uses sun.misc.Unsafe
- DirectBuffer.cleaner() - for predictable cleanup
- DirectBuffer.address() - for efficient off-heap byte arrays
Third party dependencies
- Depends on Third Party JARs
SLIDE 135 Speedment Enterprise - a Jigsaw Puzzle
Uses sun.misc.Unsafe
- DirectBuffer.cleaner() - for predictable cleanup
- DirectBuffer.address() - for efficient off-heap byte arrays
Third party dependencies
- Depends on Third Party JARs
- Automatic modules with split packages
SLIDE 136
Awaiting Community Progress
SLIDE 137 Awaiting Community Progress
SLIDE 138 Awaiting Community Progress
- OSGi bundles
- Third Party Dependencies
SLIDE 139 Awaiting Community Progress
- OSGi bundles
- Third Party Dependencies
- Split packages
SLIDE 140 Awaiting Community Progress
- OSGi bundles
- Third Party Dependencies
- Split packages
- Concealed package conflicts
SLIDE 141 Awaiting Community Progress
- OSGi bundles
- Third Party Dependencies
- Split packages
- Concealed package conflicts
- Duplicate package names
SLIDE 142 Awaiting Community Progress
- OSGi bundles
- Third Party Dependencies
- Split packages
- Concealed package conflicts
- Duplicate package names
- Spring Integration
SLIDE 143 Awaiting Community Progress
- OSGi bundles
- Third Party Dependencies
- Split packages
- Concealed package conflicts
- Duplicate package names
- Spring Integration
- Unit test frameworks
SLIDE 144
Conclusions
SLIDE 145
Conclusions
Lean Principle – "Defer Commitment" or "Decide as late as possible”
SLIDE 146 Conclusions
Lean Principle – "Defer Commitment" or "Decide as late as possible” Time well spent:
- refine application modularity,
SLIDE 147 Conclusions
Lean Principle – "Defer Commitment" or "Decide as late as possible” Time well spent:
- refine application modularity,
- rework references to non-open parts of the JDK and
SLIDE 148 Conclusions
Lean Principle – "Defer Commitment" or "Decide as late as possible” Time well spent:
- refine application modularity,
- rework references to non-open parts of the JDK and
- revisit design decisions regarding Unsafe.
SLIDE 149 Conclusions
Lean Principle – "Defer Commitment" or "Decide as late as possible” Time well spent:
- refine application modularity,
- rework references to non-open parts of the JDK and
- revisit design decisions regarding Unsafe.
Postpone Decisions (S.E.P.):
- Working around third party dependencies
SLIDE 150 Conclusions
Lean Principle – "Defer Commitment" or "Decide as late as possible” Time well spent:
- refine application modularity,
- rework references to non-open parts of the JDK and
- revisit design decisions regarding Unsafe.
Postpone Decisions (S.E.P.):
- Working around third party dependencies
- Spring Integration
SLIDE 151 Conclusions
Lean Principle – "Defer Commitment" or "Decide as late as possible” Time well spent:
- refine application modularity,
- rework references to non-open parts of the JDK and
- revisit design decisions regarding Unsafe.
Postpone Decisions (S.E.P.):
- Working around third party dependencies
- Spring Integration
- OSGi bundling
SLIDE 152 Try Speedment
github.com/speedment/speedment www.speedment.com/initializer/
SLIDE 153 Q&A
@speedment @dan_lawesson
SLIDE 154
Extra Slides for Q&A
SLIDE 155
Many-to-Many
Map<Human, List<Hare>> humanFriends = friends.stream() .collect( groupingBy(humans.finderBy(Friend.HUMAN), // Classifier mapping( hares.finderBy(Friend.HARE), //Friend to Hare finder toList() // Downstream aggregation w. List collector ) ) );
SLIDE 156 Many-to-Many
Map<Human, List<Hare>> humanFriends = friends.stream() .collect( groupingBy(humans.finderBy(Friend.HUMAN), // Classifier mapping( hares.finderBy(Friend.HARE), //Friend to Hare finder toList() // Downstream aggregation w. List collector ) ) );
Standard Java 8
SLIDE 157
Update
hares.stream() .filter(Hare.ID.equal(42)) // All Hares with ID = 42 (just one) .map(Hare.AGE.setTo(10)) // Applies a setter .forEach(hares.updater()); // Applies the updater function
SLIDE 158 Update
hares.stream() .filter(Hare.ID.equal(42)) // All Hares with ID = 42 (just one) .map(Hare.AGE.setTo(10)) // Applies a setter .forEach(hares.updater()); // Applies the updater function
Standard Java 8
SLIDE 159
Database Connectors
SLIDE 160 Beyond Open-Source
- Speedment Enterprise
- Run your database queries orders of magnitude faster!
- 10x, 100x, 1 000x, 10 000x, …
- Use the same Stream API
SLIDE 161 How is This Possible?
- No changes to user-written code
- Alternative stream source
- Data is stored in-memory
- Generates optimized serializers
for off-heap storage
SLIDE 162 In-JVM-Memory, JMH Benchmarks(*)
Benchmark Mode Cnt Score Error Units SpeedmentBenchmark.findStartsWith avgt 200 ≈ 10⁻⁵ s/op SpeedmentBenchmark.findStartsWithSql avgt 200 ≈ 10⁻⁴ s/op SpeedmentBenchmark.join avgt 200 0.476 ± 0.005 s/op SpeedmentBenchmark.joinSql avgt 200 5.174 ± 0.010 s/op SpeedmentBenchmark.sort avgt 200 ≈ 10⁻⁶ s/op SpeedmentBenchmark.sortSql avgt 200 ≈ 10⁻⁴ s/op SpeedmentBenchmark.scrollSorted avgt 200 ≈ 10⁻⁵ s/op SpeedmentBenchmark.scrollSortedSql avgt 200 24.661 ± 0.670 s/op SpeedmentBenchmark.count avgt 180 ≈ 10⁻⁸ s/op SpeedmentBenchmark.countSql avgt 200 5.143 ± 0.012 s/op (*) Preliminary results, Mac Book Pro, 2.2 GHz i7, 16GB, MySQL 5.7.16 standard with indexes on all relevant columns.
SLIDE 163 In-JVM-Memory, JMH Benchmarks(*)
Benchmark Mode Cnt Score Error Units SpeedmentBenchmark.findStartsWith avgt 200 ≈ 10⁻⁵ s/op SpeedmentBenchmark.findStartsWithSql avgt 200 ≈ 10⁻⁴ s/op SpeedmentBenchmark.join avgt 200 0.476 ± 0.005 s/op SpeedmentBenchmark.joinSql avgt 200 5.174 ± 0.010 s/op SpeedmentBenchmark.sort avgt 200 ≈ 10⁻⁶ s/op SpeedmentBenchmark.sortSql avgt 200 ≈ 10⁻⁴ s/op SpeedmentBenchmark.scrollSorted avgt 200 ≈ 10⁻⁵ s/op SpeedmentBenchmark.scrollSortedSql avgt 200 24.661 ± 0.670 s/op SpeedmentBenchmark.count avgt 180 ≈ 10⁻⁸ s/op SpeedmentBenchmark.countSql avgt 200 5.143 ± 0.012 s/op (*) Preliminary results, Mac Book Pro, 2.2 GHz i7, 16GB, MySQL 5.7.16 standard with indexes on all relevant columns. 10x
SLIDE 164 In-JVM-Memory, JMH Benchmarks(*)
Benchmark Mode Cnt Score Error Units SpeedmentBenchmark.findStartsWith avgt 200 ≈ 10⁻⁵ s/op SpeedmentBenchmark.findStartsWithSql avgt 200 ≈ 10⁻⁴ s/op SpeedmentBenchmark.join avgt 200 0.476 ± 0.005 s/op SpeedmentBenchmark.joinSql avgt 200 5.174 ± 0.010 s/op SpeedmentBenchmark.sort avgt 200 ≈ 10⁻⁶ s/op SpeedmentBenchmark.sortSql avgt 200 ≈ 10⁻⁴ s/op SpeedmentBenchmark.scrollSorted avgt 200 ≈ 10⁻⁵ s/op SpeedmentBenchmark.scrollSortedSql avgt 200 24.661 ± 0.670 s/op SpeedmentBenchmark.count avgt 180 ≈ 10⁻⁸ s/op SpeedmentBenchmark.countSql avgt 200 5.143 ± 0.012 s/op (*) Preliminary results, Mac Book Pro, 2.2 GHz i7, 16GB, MySQL 5.7.16 standard with indexes on all relevant columns. 10x >10x
SLIDE 165 In-JVM-Memory, JMH Benchmarks(*)
Benchmark Mode Cnt Score Error Units SpeedmentBenchmark.findStartsWith avgt 200 ≈ 10⁻⁵ s/op SpeedmentBenchmark.findStartsWithSql avgt 200 ≈ 10⁻⁴ s/op SpeedmentBenchmark.join avgt 200 0.476 ± 0.005 s/op SpeedmentBenchmark.joinSql avgt 200 5.174 ± 0.010 s/op SpeedmentBenchmark.sort avgt 200 ≈ 10⁻⁶ s/op SpeedmentBenchmark.sortSql avgt 200 ≈ 10⁻⁴ s/op SpeedmentBenchmark.scrollSorted avgt 200 ≈ 10⁻⁵ s/op SpeedmentBenchmark.scrollSortedSql avgt 200 24.661 ± 0.670 s/op SpeedmentBenchmark.count avgt 180 ≈ 10⁻⁸ s/op SpeedmentBenchmark.countSql avgt 200 5.143 ± 0.012 s/op (*) Preliminary results, Mac Book Pro, 2.2 GHz i7, 16GB, MySQL 5.7.16 standard with indexes on all relevant columns. 10x >10x 100x
SLIDE 166 In-JVM-Memory, JMH Benchmarks(*)
Benchmark Mode Cnt Score Error Units SpeedmentBenchmark.findStartsWith avgt 200 ≈ 10⁻⁵ s/op SpeedmentBenchmark.findStartsWithSql avgt 200 ≈ 10⁻⁴ s/op SpeedmentBenchmark.join avgt 200 0.476 ± 0.005 s/op SpeedmentBenchmark.joinSql avgt 200 5.174 ± 0.010 s/op SpeedmentBenchmark.sort avgt 200 ≈ 10⁻⁶ s/op SpeedmentBenchmark.sortSql avgt 200 ≈ 10⁻⁴ s/op SpeedmentBenchmark.scrollSorted avgt 200 ≈ 10⁻⁵ s/op SpeedmentBenchmark.scrollSortedSql avgt 200 24.661 ± 0.670 s/op SpeedmentBenchmark.count avgt 180 ≈ 10⁻⁸ s/op SpeedmentBenchmark.countSql avgt 200 5.143 ± 0.012 s/op (*) Preliminary results, Mac Book Pro, 2.2 GHz i7, 16GB, MySQL 5.7.16 standard with indexes on all relevant columns. 10x >10x 100x 2,000,000x
SLIDE 167 In-JVM-Memory, JMH Benchmarks(*)
Benchmark Mode Cnt Score Error Units SpeedmentBenchmark.findStartsWith avgt 200 ≈ 10⁻⁵ s/op SpeedmentBenchmark.findStartsWithSql avgt 200 ≈ 10⁻⁴ s/op SpeedmentBenchmark.join avgt 200 0.476 ± 0.005 s/op SpeedmentBenchmark.joinSql avgt 200 5.174 ± 0.010 s/op SpeedmentBenchmark.sort avgt 200 ≈ 10⁻⁶ s/op SpeedmentBenchmark.sortSql avgt 200 ≈ 10⁻⁴ s/op SpeedmentBenchmark.scrollSorted avgt 200 ≈ 10⁻⁵ s/op SpeedmentBenchmark.scrollSortedSql avgt 200 24.661 ± 0.670 s/op SpeedmentBenchmark.count avgt 180 ≈ 10⁻⁸ s/op SpeedmentBenchmark.countSql avgt 200 5.143 ± 0.012 s/op (*) Preliminary results, Mac Book Pro, 2.2 GHz i7, 16GB, MySQL 5.7.16 standard with indexes on all relevant columns. 10x >10x 100x 2,000,000x 500,000,000x
SLIDE 168
Gitkraken view of Jigsawing Script Commits
SLIDE 169
Gitkraken view of Jigsawing Script Commits