SlideShare a Scribd company logo
Medallia © Copyright 2016. Confidential. 1
Code Generation with JavaCompiler
for Fun, Speed, and Business Profit
Thorvald Natvig and Juan Cruz Nores
Medallia © Copyright 2015. 2
At Medallia, we collect, analyze, and display terabytes of structured &
unstructured feedback for our multibillion dollar clients in real time.
And what’s more: we have a lot of fun doing it.
Thorvald - Since 2010, growing from 70 to 1200 employees
JC - First team in Argentina office, 2011
Who we are
Hi, we’re JC & Thorvald @ Medallia
Medallia © Copyright 2016. Confidential. 3
How to run an analytics engine at 30x speed
1/30th the cost
Optimize for maximum performance with minimum engineering time
All code shown today is on GitHub
Includes bootstrap framework to do this yourself!
What’s this all about?
Fast Code in Short Time
Medallia © Copyright 2016. Confidential. 4
AGENDA 1
2
3
4
5
6
Basics of CodeGen
Problem and Java Solution
CodeGen
Learnings and Challenges
Demo!
“What’s next?”
Medallia © Copyright 2016. Confidential. 5
Two ways to generate code:
Method A: Use Java ASM and generate byte-code
You spend most of the time writing a compiler
Method B: Use Java Compiler to generate byte-code
Someone else wrote the compiler
Crash Course in Code Generation
Don’t write a compiler
Medallia © Copyright 2016. Confidential. 6
Crash Course in Code Generation
Field f = Fields.get("age");
int min = 20;
int max = 99;
long sum = records.stream()
.filter(x -> x.getValue(field) > min)
.filter(x -> x.getValue(field) < max)
.map(x -> x.getValue(field))
.mapToInt(x -> x)
.sum();
Medallia © Copyright 2016. Confidential. 7
Autoboxing and generics in general
Stream constructs
Function call to get value
Spend most of the time in “streaming”, not in “computing”
Problems!
Medallia © Copyright 2016. Confidential. 8
// Assuming the field “age” is column 3 in the datastore...
long generated(int [][] records) {
long sum = 0;
for (int i = 0; i < 88737273; ++i) {
int fieldVar1 = records[3][i];
if (fieldVar1 > 20 && fieldVar1 < 99)
sum += fieldVar1;
}
return sum;
}
Transformed code
Medallia © Copyright 2016. Confidential. 9
Generate Java code as a String
Invoke Java compiler in memory
Load generated class and instantiate an object
Call function
How to guide
“Somewhat faster”
Medallia © Copyright 2016. Confidential. 10
We live in the real world
Engineering time costs $$$; salary + lost opportunities
Often cheaper to buy hardware than spend time to optimize
Only apply this level of optimization if the saved server cost greatly
outweighs the engineering cost.
When should you do this?
Optimize for Total Cost
Medallia © Copyright 2016. Confidential. 11
AGENDA 1
2
3
4
5
6
Basics of CodeGen
Problem and Java Solution
CodeGen
Learnings and Challenges
Demo!
“What’s next?”
Medallia © Copyright 2016. Confidential. 12
An in-memory query engine
Data is a segmented 2D table, each segment an int[][]
We want to be able to execute queries such as:
newQuery()
.filter(field("a").in(1, 2, 3).or(field("b").is(3)))
.aggregate(statsAggregate("ltr"))
This is roughly equivalent to:
SELECT AVG(ltr) FROM data WHERE a IN (1, 2, 3) OR b = 3
Problem
Medallia © Copyright 2016. Confidential. 13
Query Execution
b ltr
1 10
3 7
Filter
passes? Aggregate
no
yesa
5
2
Medallia © Copyright 2016. Confidential. 14
newQuery()
.filter(field("a").in(1, 2, 3).or(field("b").is(3)))
.aggregate(statsAggregate("ltr"))
Pure Java
OR
“a” in
[1,2,3]
“b” in
[3]
Medallia © Copyright 2016. Confidential. 15
expression.visit(new ExprVisitor<Boolean>() {
public Boolean visit(AndExpr andExpr) {
return andExpr.getLeft().visit(this) && andExpr.getRight().visit(this);
}
public Boolean visit(InExpr inExpr) { /* ommitted */ }
public Boolean visit(OrExpr orExpr) {
return orExpr.getLeft().visit(this) || orExpr.getRight().visit(this);
}
/* other nodes */
});
Pure Java
Medallia © Copyright 2016. Confidential. 16
Simple query:
newQuery()
.filter(field("a").in(1, 2, 3).or(field("b").is(3)))
.aggregate(statsAggregate("ltr"))
Complex query:
newQuery()
.filter(field("a").in(1, 2, 3, 5).or(field("b").is(3)))
.filter(field("c").in(3, 5, 8, 1, 2).or(field("d").in(1,3,4)))
.filter(not(field("e").in(2, 5, 8,10,12,13,14,15,17)).or(field("f").in(1,4,2)))
.aggregate(statsAggregate("ltr"))
1M rows, split in 50k row segments (avoid large allocations)
About the benchmarks
Medallia © Copyright 2016. Confidential. 17
We actually built this
And ran some benchmarks on it:
Benchmark Mode Cnt Score Error Units
InterpretedQueryBenchmark.complexQuery thrpt 6 14.453 ± 5.557 ops/s
InterpretedQueryBenchmark.simpleQuery thrpt 6 46.057 ± 2.227 ops/s
Pure Java
Benchmark early+often
Medallia © Copyright 2016. Confidential. 18
Idea: Reduce unnecessary per-traversal operations by using lambdas
and their closures
It also reduces overall number of method calls
Take advantage of the massive optimizations implemented in HotSpot
to support Streams and lambdas (invokedynamic)
Optimized Pure Java
Medallia © Copyright 2016. Confidential. 19
@FunctionalInterface
interface Filter {
boolean eval(Segment segment, int row);
}
public Filter visit(AndExpr andExpr) {
Filter left = andExpr.getLeft().visit(this);
Filter right = andExpr.getRight().visit(this);
return (segment, row) -> left.eval(segment, row) && right.eval(segment, row);
}
Optimized Pure Java
Medallia © Copyright 2016. Confidential. 20
public Filter visit(OrExpr orExpr) {
Filter left = orExpr.getLeft().visit(this);
Filter right = orExpr.getRight().visit(this);
return (segment, row) -> left.eval(segment, row) && right.eval(segment, row);
}
public Filter visit(ConstantExpr constantExpr) {
boolean val = constantExpr.value;
return (segment, row) -> val;
}
Optimized Pure Java
Medallia © Copyright 2016. Confidential. 21
public Filter visit(InExpr inExpr) {
final int[] values = inExpr.getValues();
final int column = dataSet.getFieldByName(inExpr.getFieldName()).getColumn();
return (segment, row) -> {
int fieldVal = segment.rawData[column][row];
for (int value : values) {
if (value == fieldVal) return true;
}
return false;
};
}
Optimized Pure Java
Medallia © Copyright 2016. Confidential. 22
So we ran some benchmarks on this too:
Benchmark Mode Cnt Score Error Units
StreamQueryBenchmark.complexQuery thrpt 6 33.046 ± 2.625 ops/s
StreamQueryBenchmark.simpleQuery thrpt 6 124.077 ± 7.449 ops/s
~3X improvement on simple queries
~2X improvement on complex ones
Optimized Pure Java
Medallia © Copyright 2016. Confidential. 23
Results
Medallia © Copyright 2016. Confidential. 24
AGENDA 1
2
3
4
5
6
Basics of CodeGen
Problem and Java Solution
CodeGen
Learnings and Challenges
Demo!
“What’s next?”
Medallia © Copyright 2016. Confidential. 25
Query execution boils down to:
“iterate over every record, if it matches, aggregate”
This implies a simple query structure:
for (int i = 0; i < numRecords; i++) {
if (/* record matches */) {
/* aggregate */
}
}
Only the filter and the aggregate depend on the query
CodeGen
Medallia © Copyright 2016. Confidential. 26
cg.print(query.buildExpressionTree().visit(new ExprVisitor<String>() {
public String visit(AndExpr andExpr) {
return "(" +andExpr.getLeft().visit(this) +" && "+ andExpr.getRight().visit(this) + ")";
}
public String visit(InExpr inExpr) {
FieldDefinition field = dataSet.getFieldByName(inExpr.getFieldName());
return "(" + IntStream.of(inExpr.getValues())
.mapToObj(v -> String.format("rawData[%d][row] == %dL", field.getColumn(), v))
.reduce((a,b) -> a + " || " + b)
.orElseThrow(() -> new RuntimeException("empty filter"))
+ ")";
}
public String visit(NotExpr notExpr) { "!" + notExpr.getTarget().visit(this); }
public String visit(OrExpr orExpr) { return "(" +orExpr.getLeft().visit(this) + " || " + orExpr.getRight().visit(this) + ")"; }
public String visit(ConstantExpr constantExpr) { return String.valueOf(constantExpr.value); }
}));
Naive CodeGen
Medallia © Copyright 2016. Confidential. 27
public void process(Segment segment) {
int[][] rawData = segment.rawData;
int nRows = rawData[0].length;
FieldStats result$1 = (FieldStats)this.result;
for (int row = 0; row < nRows; row++) {
if ((rawData[0][row] == 1L || rawData[0][row] == 2L
|| rawData[0][row] == 3L) || (rawData[1][row] == 3L)) {
result$1.count++;
result$1.sum += rawData[6][row];
}
}
}
Naive CodeGen
Medallia © Copyright 2016. Confidential. 28
Benchmark Mode Cnt Score Error Units
CompiledQuery.complexQuery thrpt 6 72.509 ± 13.526 ops/s
CompiledQuery.simpleQuery thrpt 6 208.281 ± 11.335 ops/s
~4X improvement on simple queries (over the simple interpreter)
~5X improvement on complex ones
Results
Medallia © Copyright 2016. Confidential. 29
Results
Medallia © Copyright 2016. Confidential. 30
Higher level transforms
extract common subexpressions
order filters to maximize the chance of rejecting a filter
...
many of these apply also to the interpreter
Low level transforms
branch reduction
perfect hashing
...
Optimizing Your CodeGen
Medallia © Copyright 2016. Confidential. 31
General strategy: instead of a set.contains() or set of ‘==’ comparisons
Less than 3 values: a or b or c
Value-range <= 64: reverse inverted bitmask.
Value-range <= 1024: array of reverse inverted bitmask.
Otherwise: Generated Perfect Hash
Branch Reduction
Medallia © Copyright 2016. Confidential. 32
Branch reduction
1 0 0 0 0 0 0 0 >>> test-val
0 1 0 0 0 0 0 0
0 0 0 1 0 0 0 0
0 0 0 0 1 0 0 0
0 0 0 0 0 0 0 1
1:
3:
4:
7:
0 1 0 1 1 0 0 1mask:
bitwise or
field("a")
.in(1, 3, 4, 7)
Medallia © Copyright 2016. Confidential. 33
Evaluation
1:
2:
0 1 0 1 1 0 0 1(
field("a")
.in(1, 3, 4, 7)
<< fieldVal ) < 0
01 0 1 1 0 0 1
00 1 1 0 0 1 0
Field
Value
✅
❌
= -78
= 100
Medallia © Copyright 2016. Confidential. 34
newQuery()
.filter(field("a").in(1, 2, 3, 9).or(field("b").is(3)))
.aggregate(statsAggregate("ltr"));
public void process(Segment segment) {
int[][] rawData = segment.rawData;
int nRows = rawData[0].length;
FieldStats result$1 = (FieldStats)this.result;
for (int row = 0; row < nRows; row++) {
if (((0x7040000000000000L << rawData[0][row]) < 0 || (rawData[1][row] == 3L))) {
result$1.count++;
result$1.sum += rawData[2][row];
}
}
}
Variant Code Generation
Medallia © Copyright 2016. Confidential. 35
protected String generateInExpr(JavaCodeGenerator cg, InExpr inExpr) {
final FieldDefinition fieldDef = dataSet.getFieldByName(inExpr.getFieldName());
final FieldSpec fieldSpec = fieldDef.getFieldSpec();
final int numValues = fieldSpec.getBound() - fieldSpec.getOrigin();
final int[] inValues = inExpr.getValues();
if (inValues.length > 3 && numValues < 64) {
long mask = 0;
for (int value : inValues) {
mask |= 0x8000_0000_0000_0000L >>> (value - fieldSpec.getOrigin());
}
if (fieldSpec.getOrigin() == 0) {
return String.format("(0x%xL << rawData[%d][row]) < 0", mask, fieldDef.getColumn());
} else {
return String.format("(0x%xL << (rawData[%d][row]-%dL)) < 0", mask, fieldDef.getColumn(), fieldSpec.getOrigin());
}
}
// Other cases, fall back to the naive one
return super.generateInExpr(cg, inExpr);
}
Variant Code Generation
Medallia © Copyright 2016. Confidential. 36
Benchmark Mode Cnt Score Error Units
VariantQueryBenchmark.complexQuery thrpt 6 88.972 ± 2.206 ops/s
VariantQueryBenchmark.simpleQuery thrpt 6 210.281 ± 8.007 ops/s
about the same on simple queries (over the naive compiler)
~20% improvement on complex ones
Results
Medallia © Copyright 2016. Confidential. 37
Results
Medallia © Copyright 2016. Confidential. 38
AGENDA 1
2
3
4
5
6
Basics of CodeGen
Problem and Java Solution
CodeGen
Learnings and Challenges
Demo!
“What’s next?”
Medallia © Copyright 2016. Confidential. 39
public void process(com.medallia.data.Segment);
Code:
// Save Segment.rawData into a local variable (var 2)
0: aload_1
1: getfield #3
4: astore_2
// get rawData[0].length and store it
// in a local variable (var 3)
5: aload_2
6: iconst_0
7: aaload
8: arraylength
9: istore_3
// cast this.result into a FieldStats object and store it in a variable (var 4)
10: aload_0
11: getfield #2 // Field result:Ljava/lang/Object;
14: checkcast #4 // class FieldStats
17: astore 4
Why not do bytecode?
Medallia © Copyright 2016. Confidential. 40
// Begin the loop
// set i = 0 (var 5)
19: iconst_0
20: istore 5
// if i >= (var 3) -- number of rows
// jump to end the loop (jump to instr 113)
22: iload 5
24: iload_3
25: if_icmpge 113
// rawData[0][i] == 1 goto 78
28: aload_2
29: iconst_0
30: aaload
31: iload 5
33: laload
34: lconst_1
35: lcmp
36: ifeq 78
// rawData[0][i] == 2 goto 78
… (more conditions)
Why not do bytecode?
… (more conditions)
// fieldStats (var 4).count ++
78: aload 4
80: dup
81: getfield #9 // Field FieldStats.count:J
84: lconst_1
85: ladd
86: putfield #9 // Field FieldStats.count:J
// fieldStats (var 4).sum += rawData[6][i]
89: aload 4
91: dup
92: getfield #10 // Field FieldStats.sum:D
95: aload_2
96: bipush 6
98: aaload
99: iload 5
101: laload
102: l2d
103: dadd
104: putfield #10 // Field FieldStats.sum:D
// i++ (var 5), jump to 22 (loop start)
107: iinc 5, 1
110: goto 22
113: return
}
Medallia © Copyright 2016. Confidential. 41
Javac is designed as a command line tool
but… API in javax.tools!
For the basic case we have to deal with three entities:
Source files (input)
Class files (output)
Classpath
File operations are abstracted behind JavaFileManager
Compiling in-memory
Medallia © Copyright 2016. Confidential. 42
Be careful with multithreading
Cache warmup is the most time consuming part of compilation
Simple strategy:
Keep a JavaCompiler and a StandardJavaFileManager in a thread
local variable
Use a fixed size thread pool to constrain memory usage
Compiling in-memory
Medallia © Copyright 2016. Confidential. 43
Classloading
The simplest strategy is to use one class per ClassLoader:
public static <T> Class<? extends T> classFromBytes(
final Class<T> baseClass, final String name, final byte[] bytecode) {
return new ClassLoader(baseClass.getClassLoader()) {
Class<? extends T> c = defineClass(name, bytecode, 0, bytecode.length)
.asSubclass(baseClass);
}.c;
}
Medallia © Copyright 2016. Confidential. 44
Pros:
Easy to implement
Memory reclamation is easy
(each class/classloader pair is independent)
Cons:
Metaspace chunks are tied to a classloader
→ wasted metaspace
Constrained to generating a single class
Classloading
Medallia © Copyright 2016. Confidential. 45
Most Java programs are fairly static
JVM needs to warm up new code
Interpreter
C1 (-client compiler): fast compilation
C2 (-server compiler): 20%-30% faster code for some workloads
Dynamic class loading breaks some assumptions
code size increases over application run time
compiled code size does too: HotSpot CodeCache
Classloading
Medallia © Copyright 2016. Confidential. 46
HotSpot stores native code in its code cache
You can run out of it
If you do, the compilers are disabled
"CodeCache is full. Compiler has been disabled"
Some JVM options to deal with it:
-XX:InitialCodeCacheSize
-XX:ReservedCodeCacheSize
-XX:+UseCodeCacheFlushing
CodeCache
Medallia © Copyright 2016. Confidential. 47
AGENDA 1
2
3
4
5
6
Basics of CodeGen
Problem and Java Solution
CodeGen
Learnings and Challenges
Demo!
“What’s next?”
Medallia © Copyright 2016. Confidential. 48
Demo
Medallia © Copyright 2016. Confidential. 49
AGENDA 1
2
3
4
5
6
Basics of CodeGen
Problem and Java Solution
CodeGen
Learnings and Challenges
Demo!
“What’s next?”
Medallia © Copyright 2016. Confidential. 50
As in x86-64 assembly.
And yes, YES WE ARE.
We’re just one step away from ASM
Medallia © Copyright 2016. Confidential. 51
Clang as a library
Compile in-memory and execute C++ code
Using medallia/unsafe (open source!)
Java↔C++ argument marshalling
Implement native methods on-the-fly!
Generating C++ on-the-fly
Medallia © Copyright 2016. Confidential. 52
#include <jni.h>
/* omitted - initialization of field constants */
void process(JNIEnv* env, jobject self, jobject segment) {
jint* rawData[cols];
/* omitted - get raw data arrays */
jdouble sum = 0;
jlong count = 0;
for (int row = 0; row < (int)nRows; row++) {
if (((rawData[0][row] == 1L || rawData[0][row] == 2L || rawData[0][row] == 3L) || (rawData[1][row] == 3L))) {
count++;
sum += rawData[6][row];
}
}
/* omitted - release raw data arrays */
jobject result = env->GetObjectField(self, resultFld);
env->SetLongField(result, countFld, env->GetLongField(result, countFld) + count);
env->SetDoubleField(result, sumFld, env->GetDoubleField(result, sumFld) + sum);
}
C++ query
Medallia © Copyright 2016. Confidential. 53
Benchmark Mode Cnt Score Error Units
Unsafe.complexQuery thrpt 6 97.135 ± 4.905 ops/s
Unsafe.simpleQuery thrpt 6 251.735 ± 14.856 ops/s
~20% improvement on simple queries (over the variant compiler)
~35% improvement on complex ones
C++ query
Medallia © Copyright 2016. Confidential. 54
Results
Medallia © Copyright 2016. Confidential. 55
Java can now segfault.
Using codegen limits probability of “incident”
Not recommended.
But fun.
C++ violates everything Java
Medallia © Copyright 2016. Confidential. 56
CodeGen is easy (and also fun)
Focus on generating String code
Faster to write
Just as fast to execute (and often faster)
Easy to debug
Spend your time wisely
Bottom Line
Medallia © Copyright 2016. Confidential. 57
Code for this talk:
https://github.com/medallia/javaone2016
Clang as a library:
https://github.com/medallia/unsafe
Thank you!

More Related Content

What's hot

concurrency gpars
concurrency gparsconcurrency gpars
concurrency gparsPaul King
 
Java Puzzle
Java PuzzleJava Puzzle
Java PuzzleSFilipp
 
Industrial Strength Groovy - Tools for the Professional Groovy Developer: Pau...
Industrial Strength Groovy - Tools for the Professional Groovy Developer: Pau...Industrial Strength Groovy - Tools for the Professional Groovy Developer: Pau...
Industrial Strength Groovy - Tools for the Professional Groovy Developer: Pau...Paul King
 
JDK8: Stream style
JDK8: Stream styleJDK8: Stream style
JDK8: Stream style
Sergey Kuksenko
 
Drools rule Concepts
Drools rule ConceptsDrools rule Concepts
Drools rule Concepts
RaviShankar Mishra
 
Getting start Java EE Action-Based MVC with Thymeleaf
Getting start Java EE Action-Based MVC with ThymeleafGetting start Java EE Action-Based MVC with Thymeleaf
Getting start Java EE Action-Based MVC with Thymeleaf
Masatoshi Tada
 
The Ring programming language version 1.9 book - Part 99 of 210
The Ring programming language version 1.9 book - Part 99 of 210The Ring programming language version 1.9 book - Part 99 of 210
The Ring programming language version 1.9 book - Part 99 of 210
Mahmoud Samir Fayed
 
JBoss Drools - Pure Java Rule Engine
JBoss Drools - Pure Java Rule EngineJBoss Drools - Pure Java Rule Engine
JBoss Drools - Pure Java Rule Engine
Anil Allewar
 
Java puzzles
Java puzzlesJava puzzles
Java puzzles
Nikola Petrov
 
Developing Configurable and High Performance Apps in Drools
Developing Configurable and High Performance Apps in Drools Developing Configurable and High Performance Apps in Drools
Developing Configurable and High Performance Apps in Drools
Ajay Mahajan
 
GPars (Groovy Parallel Systems)
GPars (Groovy Parallel Systems)GPars (Groovy Parallel Systems)
GPars (Groovy Parallel Systems)
Gagan Agrawal
 
Optimizing Slow Queries with Indexes and Creativity
Optimizing Slow Queries with Indexes and CreativityOptimizing Slow Queries with Indexes and Creativity
Optimizing Slow Queries with Indexes and CreativityMongoDB
 
Introducing Drools
Introducing DroolsIntroducing Drools
Introducing DroolsMario Fusco
 
Requery overview
Requery overviewRequery overview
Requery overview
Sunghyouk Bae
 
18(ish) Things You'll Love About Oracle Database 18c
18(ish) Things You'll Love About Oracle Database 18c18(ish) Things You'll Love About Oracle Database 18c
18(ish) Things You'll Love About Oracle Database 18c
Chris Saxon
 
Eric Lafortune - ProGuard: Optimizer and obfuscator in the Android SDK
Eric Lafortune - ProGuard: Optimizer and obfuscator in the Android SDKEric Lafortune - ProGuard: Optimizer and obfuscator in the Android SDK
Eric Lafortune - ProGuard: Optimizer and obfuscator in the Android SDK
GuardSquare
 
Rule Engine & Drools
Rule Engine & DroolsRule Engine & Drools
Rule Engine & Drools
Sandip Jadhav
 
Kpi driven-java-development-fn conf
Kpi driven-java-development-fn confKpi driven-java-development-fn conf
Kpi driven-java-development-fn conf
Anirban Bhattacharjee
 

What's hot (20)

concurrency gpars
concurrency gparsconcurrency gpars
concurrency gpars
 
Java Puzzle
Java PuzzleJava Puzzle
Java Puzzle
 
Industrial Strength Groovy - Tools for the Professional Groovy Developer: Pau...
Industrial Strength Groovy - Tools for the Professional Groovy Developer: Pau...Industrial Strength Groovy - Tools for the Professional Groovy Developer: Pau...
Industrial Strength Groovy - Tools for the Professional Groovy Developer: Pau...
 
JDK8: Stream style
JDK8: Stream styleJDK8: Stream style
JDK8: Stream style
 
Drools rule Concepts
Drools rule ConceptsDrools rule Concepts
Drools rule Concepts
 
Getting start Java EE Action-Based MVC with Thymeleaf
Getting start Java EE Action-Based MVC with ThymeleafGetting start Java EE Action-Based MVC with Thymeleaf
Getting start Java EE Action-Based MVC with Thymeleaf
 
The Ring programming language version 1.9 book - Part 99 of 210
The Ring programming language version 1.9 book - Part 99 of 210The Ring programming language version 1.9 book - Part 99 of 210
The Ring programming language version 1.9 book - Part 99 of 210
 
JBoss Drools - Pure Java Rule Engine
JBoss Drools - Pure Java Rule EngineJBoss Drools - Pure Java Rule Engine
JBoss Drools - Pure Java Rule Engine
 
Java puzzles
Java puzzlesJava puzzles
Java puzzles
 
Drools Ecosystem
Drools EcosystemDrools Ecosystem
Drools Ecosystem
 
Developing Configurable and High Performance Apps in Drools
Developing Configurable and High Performance Apps in Drools Developing Configurable and High Performance Apps in Drools
Developing Configurable and High Performance Apps in Drools
 
GPars (Groovy Parallel Systems)
GPars (Groovy Parallel Systems)GPars (Groovy Parallel Systems)
GPars (Groovy Parallel Systems)
 
Optimizing Slow Queries with Indexes and Creativity
Optimizing Slow Queries with Indexes and CreativityOptimizing Slow Queries with Indexes and Creativity
Optimizing Slow Queries with Indexes and Creativity
 
Introducing Drools
Introducing DroolsIntroducing Drools
Introducing Drools
 
Drools
DroolsDrools
Drools
 
Requery overview
Requery overviewRequery overview
Requery overview
 
18(ish) Things You'll Love About Oracle Database 18c
18(ish) Things You'll Love About Oracle Database 18c18(ish) Things You'll Love About Oracle Database 18c
18(ish) Things You'll Love About Oracle Database 18c
 
Eric Lafortune - ProGuard: Optimizer and obfuscator in the Android SDK
Eric Lafortune - ProGuard: Optimizer and obfuscator in the Android SDKEric Lafortune - ProGuard: Optimizer and obfuscator in the Android SDK
Eric Lafortune - ProGuard: Optimizer and obfuscator in the Android SDK
 
Rule Engine & Drools
Rule Engine & DroolsRule Engine & Drools
Rule Engine & Drools
 
Kpi driven-java-development-fn conf
Kpi driven-java-development-fn confKpi driven-java-development-fn conf
Kpi driven-java-development-fn conf
 

Viewers also liked

Deprogramming Gender Bias
Deprogramming Gender Bias Deprogramming Gender Bias
Deprogramming Gender Bias
Lauren Jackman
 
Fire Fighting Certificate - 106622
Fire Fighting Certificate - 106622Fire Fighting Certificate - 106622
Fire Fighting Certificate - 106622Hussain Al-Khabbaz
 
CIS13: Don't Let Mobile be the Achilles Heel for Your Enterprise Security
CIS13: Don't Let Mobile be the Achilles Heel for Your Enterprise SecurityCIS13: Don't Let Mobile be the Achilles Heel for Your Enterprise Security
CIS13: Don't Let Mobile be the Achilles Heel for Your Enterprise Security
CloudIDSummit
 
Days of Zscaler
Days of ZscalerDays of Zscaler
Days of Zscaler
Alan Dong
 
Sell More with Paid Search & BigCommerce
Sell More with Paid Search & BigCommerceSell More with Paid Search & BigCommerce
Sell More with Paid Search & BigCommerce
Groove Commerce
 
DLS Strategies - Criaçao da Plataforma de Marketing Intelligence - 2014
DLS Strategies - Criaçao da Plataforma de Marketing Intelligence - 2014DLS Strategies - Criaçao da Plataforma de Marketing Intelligence - 2014
DLS Strategies - Criaçao da Plataforma de Marketing Intelligence - 2014Stephanie De Lima
 
Sailpoint Training | Best Sailpoint IdentityIQ Online Course -GOT
Sailpoint Training | Best Sailpoint IdentityIQ Online Course -GOTSailpoint Training | Best Sailpoint IdentityIQ Online Course -GOT
Sailpoint Training | Best Sailpoint IdentityIQ Online Course -GOT
Global Online Trainings
 
Recruiting Optimization Roadshow - Mike Podobnik, Medallia
Recruiting Optimization Roadshow - Mike Podobnik, MedalliaRecruiting Optimization Roadshow - Mike Podobnik, Medallia
Recruiting Optimization Roadshow - Mike Podobnik, Medallia
GreenhouseSoftware
 
Guest Survey Systems Medallia By Michael Allen
Guest Survey Systems Medallia By Michael AllenGuest Survey Systems Medallia By Michael Allen
Guest Survey Systems Medallia By Michael Allen
Michael Allen
 
Data Exploration and Analytics for the Modern Business
Data Exploration and Analytics for the Modern BusinessData Exploration and Analytics for the Modern Business
Data Exploration and Analytics for the Modern Business
DATAVERSITY
 
SCIM 2.0 - Choose your own identity adventure
SCIM 2.0 - Choose your own identity adventureSCIM 2.0 - Choose your own identity adventure
SCIM 2.0 - Choose your own identity adventure
Kelly Grizzle
 
Microservices using relocatable Docker containers
Microservices using relocatable Docker containersMicroservices using relocatable Docker containers
Microservices using relocatable Docker containers
Mauricio Garavaglia
 
Cloudflare
CloudflareCloudflare
Cloudflare
Fadi Abdulwahab
 
Phunware webinar future of connected health
Phunware webinar future of connected healthPhunware webinar future of connected health
Phunware webinar future of connected health
Phunware
 
Apttus Quote-to-Cash Impact Study
Apttus Quote-to-Cash Impact StudyApttus Quote-to-Cash Impact Study
Apttus Quote-to-Cash Impact Study
Apttus
 
First Aid in Hospitality Industry
First Aid in Hospitality IndustryFirst Aid in Hospitality Industry
First Aid in Hospitality Industry
Raghav Lalvani
 
How to Execute Your CX Vision
How to Execute Your CX VisionHow to Execute Your CX Vision
How to Execute Your CX Vision
Qualtrics
 
Work is a Relationship, Act Accordingly
Work is a Relationship, Act AccordinglyWork is a Relationship, Act Accordingly
Work is a Relationship, Act Accordingly
Qualtrics
 
Pulse Surveys // What, When, How and Why?
Pulse Surveys // What, When, How and Why?Pulse Surveys // What, When, How and Why?
Pulse Surveys // What, When, How and Why?
Qualtrics
 
Humanity Means Business: Why Culture Eats Strategy for Breakfast
Humanity Means Business: Why Culture Eats Strategy for BreakfastHumanity Means Business: Why Culture Eats Strategy for Breakfast
Humanity Means Business: Why Culture Eats Strategy for Breakfast
Qualtrics
 

Viewers also liked (20)

Deprogramming Gender Bias
Deprogramming Gender Bias Deprogramming Gender Bias
Deprogramming Gender Bias
 
Fire Fighting Certificate - 106622
Fire Fighting Certificate - 106622Fire Fighting Certificate - 106622
Fire Fighting Certificate - 106622
 
CIS13: Don't Let Mobile be the Achilles Heel for Your Enterprise Security
CIS13: Don't Let Mobile be the Achilles Heel for Your Enterprise SecurityCIS13: Don't Let Mobile be the Achilles Heel for Your Enterprise Security
CIS13: Don't Let Mobile be the Achilles Heel for Your Enterprise Security
 
Days of Zscaler
Days of ZscalerDays of Zscaler
Days of Zscaler
 
Sell More with Paid Search & BigCommerce
Sell More with Paid Search & BigCommerceSell More with Paid Search & BigCommerce
Sell More with Paid Search & BigCommerce
 
DLS Strategies - Criaçao da Plataforma de Marketing Intelligence - 2014
DLS Strategies - Criaçao da Plataforma de Marketing Intelligence - 2014DLS Strategies - Criaçao da Plataforma de Marketing Intelligence - 2014
DLS Strategies - Criaçao da Plataforma de Marketing Intelligence - 2014
 
Sailpoint Training | Best Sailpoint IdentityIQ Online Course -GOT
Sailpoint Training | Best Sailpoint IdentityIQ Online Course -GOTSailpoint Training | Best Sailpoint IdentityIQ Online Course -GOT
Sailpoint Training | Best Sailpoint IdentityIQ Online Course -GOT
 
Recruiting Optimization Roadshow - Mike Podobnik, Medallia
Recruiting Optimization Roadshow - Mike Podobnik, MedalliaRecruiting Optimization Roadshow - Mike Podobnik, Medallia
Recruiting Optimization Roadshow - Mike Podobnik, Medallia
 
Guest Survey Systems Medallia By Michael Allen
Guest Survey Systems Medallia By Michael AllenGuest Survey Systems Medallia By Michael Allen
Guest Survey Systems Medallia By Michael Allen
 
Data Exploration and Analytics for the Modern Business
Data Exploration and Analytics for the Modern BusinessData Exploration and Analytics for the Modern Business
Data Exploration and Analytics for the Modern Business
 
SCIM 2.0 - Choose your own identity adventure
SCIM 2.0 - Choose your own identity adventureSCIM 2.0 - Choose your own identity adventure
SCIM 2.0 - Choose your own identity adventure
 
Microservices using relocatable Docker containers
Microservices using relocatable Docker containersMicroservices using relocatable Docker containers
Microservices using relocatable Docker containers
 
Cloudflare
CloudflareCloudflare
Cloudflare
 
Phunware webinar future of connected health
Phunware webinar future of connected healthPhunware webinar future of connected health
Phunware webinar future of connected health
 
Apttus Quote-to-Cash Impact Study
Apttus Quote-to-Cash Impact StudyApttus Quote-to-Cash Impact Study
Apttus Quote-to-Cash Impact Study
 
First Aid in Hospitality Industry
First Aid in Hospitality IndustryFirst Aid in Hospitality Industry
First Aid in Hospitality Industry
 
How to Execute Your CX Vision
How to Execute Your CX VisionHow to Execute Your CX Vision
How to Execute Your CX Vision
 
Work is a Relationship, Act Accordingly
Work is a Relationship, Act AccordinglyWork is a Relationship, Act Accordingly
Work is a Relationship, Act Accordingly
 
Pulse Surveys // What, When, How and Why?
Pulse Surveys // What, When, How and Why?Pulse Surveys // What, When, How and Why?
Pulse Surveys // What, When, How and Why?
 
Humanity Means Business: Why Culture Eats Strategy for Breakfast
Humanity Means Business: Why Culture Eats Strategy for BreakfastHumanity Means Business: Why Culture Eats Strategy for Breakfast
Humanity Means Business: Why Culture Eats Strategy for Breakfast
 

Similar to JavaOne 2016: Code Generation with JavaCompiler for Fun, Speed and Business Profit

RivieraJUG - MySQL Indexes and Histograms
RivieraJUG - MySQL Indexes and HistogramsRivieraJUG - MySQL Indexes and Histograms
RivieraJUG - MySQL Indexes and Histograms
Frederic Descamps
 
Low latency in java 8 by Peter Lawrey
Low latency in java 8 by Peter Lawrey Low latency in java 8 by Peter Lawrey
Low latency in java 8 by Peter Lawrey
J On The Beach
 
The value of reactive
The value of reactiveThe value of reactive
The value of reactive
Stéphane Maldini
 
The Value of Reactive
The Value of ReactiveThe Value of Reactive
The Value of Reactive
VMware Tanzu
 
Java 5 6 Generics, Concurrency, Garbage Collection, Tuning
Java 5 6 Generics, Concurrency, Garbage Collection, TuningJava 5 6 Generics, Concurrency, Garbage Collection, Tuning
Java 5 6 Generics, Concurrency, Garbage Collection, TuningCarol McDonald
 
Graal and Truffle: One VM to Rule Them All
Graal and Truffle: One VM to Rule Them AllGraal and Truffle: One VM to Rule Them All
Graal and Truffle: One VM to Rule Them All
Thomas Wuerthinger
 
00_Introduction to Java.ppt
00_Introduction to Java.ppt00_Introduction to Java.ppt
00_Introduction to Java.ppt
HongAnhNguyn285885
 
Cassandra Tools and Distributed Administration (Jeffrey Berger, Knewton) | C*...
Cassandra Tools and Distributed Administration (Jeffrey Berger, Knewton) | C*...Cassandra Tools and Distributed Administration (Jeffrey Berger, Knewton) | C*...
Cassandra Tools and Distributed Administration (Jeffrey Berger, Knewton) | C*...
DataStax
 
Lambdas puzzler - Peter Lawrey
Lambdas puzzler - Peter LawreyLambdas puzzler - Peter Lawrey
Lambdas puzzler - Peter Lawrey
JAXLondon_Conference
 
Low latency in java 8 v5
Low latency in java 8 v5Low latency in java 8 v5
Low latency in java 8 v5
Peter Lawrey
 
Shooting the Rapids
Shooting the RapidsShooting the Rapids
Shooting the Rapids
Maurice Naftalin
 
Open Source 101 2022 - MySQL Indexes and Histograms
Open Source 101 2022 - MySQL Indexes and HistogramsOpen Source 101 2022 - MySQL Indexes and Histograms
Open Source 101 2022 - MySQL Indexes and Histograms
Frederic Descamps
 
Machine-learning based performance heuristics for Runtime CPU/GPU Selection i...
Machine-learning based performance heuristics for Runtime CPU/GPU Selection i...Machine-learning based performance heuristics for Runtime CPU/GPU Selection i...
Machine-learning based performance heuristics for Runtime CPU/GPU Selection i...
Akihiro Hayashi
 
SnappyData Ad Analytics Use Case -- BDAM Meetup Sept 14th
SnappyData Ad Analytics Use Case -- BDAM Meetup Sept 14thSnappyData Ad Analytics Use Case -- BDAM Meetup Sept 14th
SnappyData Ad Analytics Use Case -- BDAM Meetup Sept 14th
SnappyData
 
Scala to assembly
Scala to assemblyScala to assembly
Scala to assembly
Jarek Ratajski
 
Performance Optimization of Rails Applications
Performance Optimization of Rails ApplicationsPerformance Optimization of Rails Applications
Performance Optimization of Rails ApplicationsSerge Smetana
 
Using Bayesian Optimization to Tune Machine Learning Models
Using Bayesian Optimization to Tune Machine Learning ModelsUsing Bayesian Optimization to Tune Machine Learning Models
Using Bayesian Optimization to Tune Machine Learning Models
Scott Clark
 
Using Bayesian Optimization to Tune Machine Learning Models
Using Bayesian Optimization to Tune Machine Learning ModelsUsing Bayesian Optimization to Tune Machine Learning Models
Using Bayesian Optimization to Tune Machine Learning Models
SigOpt
 
Innovative Specifications for Better Performance Logging and Monitoring
Innovative Specifications for Better Performance Logging and MonitoringInnovative Specifications for Better Performance Logging and Monitoring
Innovative Specifications for Better Performance Logging and Monitoring
Cary Millsap
 
Performance and how to measure it - ProgSCon London 2016
Performance and how to measure it - ProgSCon London 2016Performance and how to measure it - ProgSCon London 2016
Performance and how to measure it - ProgSCon London 2016
Matt Warren
 

Similar to JavaOne 2016: Code Generation with JavaCompiler for Fun, Speed and Business Profit (20)

RivieraJUG - MySQL Indexes and Histograms
RivieraJUG - MySQL Indexes and HistogramsRivieraJUG - MySQL Indexes and Histograms
RivieraJUG - MySQL Indexes and Histograms
 
Low latency in java 8 by Peter Lawrey
Low latency in java 8 by Peter Lawrey Low latency in java 8 by Peter Lawrey
Low latency in java 8 by Peter Lawrey
 
The value of reactive
The value of reactiveThe value of reactive
The value of reactive
 
The Value of Reactive
The Value of ReactiveThe Value of Reactive
The Value of Reactive
 
Java 5 6 Generics, Concurrency, Garbage Collection, Tuning
Java 5 6 Generics, Concurrency, Garbage Collection, TuningJava 5 6 Generics, Concurrency, Garbage Collection, Tuning
Java 5 6 Generics, Concurrency, Garbage Collection, Tuning
 
Graal and Truffle: One VM to Rule Them All
Graal and Truffle: One VM to Rule Them AllGraal and Truffle: One VM to Rule Them All
Graal and Truffle: One VM to Rule Them All
 
00_Introduction to Java.ppt
00_Introduction to Java.ppt00_Introduction to Java.ppt
00_Introduction to Java.ppt
 
Cassandra Tools and Distributed Administration (Jeffrey Berger, Knewton) | C*...
Cassandra Tools and Distributed Administration (Jeffrey Berger, Knewton) | C*...Cassandra Tools and Distributed Administration (Jeffrey Berger, Knewton) | C*...
Cassandra Tools and Distributed Administration (Jeffrey Berger, Knewton) | C*...
 
Lambdas puzzler - Peter Lawrey
Lambdas puzzler - Peter LawreyLambdas puzzler - Peter Lawrey
Lambdas puzzler - Peter Lawrey
 
Low latency in java 8 v5
Low latency in java 8 v5Low latency in java 8 v5
Low latency in java 8 v5
 
Shooting the Rapids
Shooting the RapidsShooting the Rapids
Shooting the Rapids
 
Open Source 101 2022 - MySQL Indexes and Histograms
Open Source 101 2022 - MySQL Indexes and HistogramsOpen Source 101 2022 - MySQL Indexes and Histograms
Open Source 101 2022 - MySQL Indexes and Histograms
 
Machine-learning based performance heuristics for Runtime CPU/GPU Selection i...
Machine-learning based performance heuristics for Runtime CPU/GPU Selection i...Machine-learning based performance heuristics for Runtime CPU/GPU Selection i...
Machine-learning based performance heuristics for Runtime CPU/GPU Selection i...
 
SnappyData Ad Analytics Use Case -- BDAM Meetup Sept 14th
SnappyData Ad Analytics Use Case -- BDAM Meetup Sept 14thSnappyData Ad Analytics Use Case -- BDAM Meetup Sept 14th
SnappyData Ad Analytics Use Case -- BDAM Meetup Sept 14th
 
Scala to assembly
Scala to assemblyScala to assembly
Scala to assembly
 
Performance Optimization of Rails Applications
Performance Optimization of Rails ApplicationsPerformance Optimization of Rails Applications
Performance Optimization of Rails Applications
 
Using Bayesian Optimization to Tune Machine Learning Models
Using Bayesian Optimization to Tune Machine Learning ModelsUsing Bayesian Optimization to Tune Machine Learning Models
Using Bayesian Optimization to Tune Machine Learning Models
 
Using Bayesian Optimization to Tune Machine Learning Models
Using Bayesian Optimization to Tune Machine Learning ModelsUsing Bayesian Optimization to Tune Machine Learning Models
Using Bayesian Optimization to Tune Machine Learning Models
 
Innovative Specifications for Better Performance Logging and Monitoring
Innovative Specifications for Better Performance Logging and MonitoringInnovative Specifications for Better Performance Logging and Monitoring
Innovative Specifications for Better Performance Logging and Monitoring
 
Performance and how to measure it - ProgSCon London 2016
Performance and how to measure it - ProgSCon London 2016Performance and how to measure it - ProgSCon London 2016
Performance and how to measure it - ProgSCon London 2016
 

Recently uploaded

Gamify Your Mind; The Secret Sauce to Delivering Success, Continuously Improv...
Gamify Your Mind; The Secret Sauce to Delivering Success, Continuously Improv...Gamify Your Mind; The Secret Sauce to Delivering Success, Continuously Improv...
Gamify Your Mind; The Secret Sauce to Delivering Success, Continuously Improv...
Shahin Sheidaei
 
Custom Healthcare Software for Managing Chronic Conditions and Remote Patient...
Custom Healthcare Software for Managing Chronic Conditions and Remote Patient...Custom Healthcare Software for Managing Chronic Conditions and Remote Patient...
Custom Healthcare Software for Managing Chronic Conditions and Remote Patient...
Mind IT Systems
 
Vitthal Shirke Microservices Resume Montevideo
Vitthal Shirke Microservices Resume MontevideoVitthal Shirke Microservices Resume Montevideo
Vitthal Shirke Microservices Resume Montevideo
Vitthal Shirke
 
How Recreation Management Software Can Streamline Your Operations.pptx
How Recreation Management Software Can Streamline Your Operations.pptxHow Recreation Management Software Can Streamline Your Operations.pptx
How Recreation Management Software Can Streamline Your Operations.pptx
wottaspaceseo
 
Beyond Event Sourcing - Embracing CRUD for Wix Platform - Java.IL
Beyond Event Sourcing - Embracing CRUD for Wix Platform - Java.ILBeyond Event Sourcing - Embracing CRUD for Wix Platform - Java.IL
Beyond Event Sourcing - Embracing CRUD for Wix Platform - Java.IL
Natan Silnitsky
 
Cracking the code review at SpringIO 2024
Cracking the code review at SpringIO 2024Cracking the code review at SpringIO 2024
Cracking the code review at SpringIO 2024
Paco van Beckhoven
 
Graphic Design Crash Course for beginners
Graphic Design Crash Course for beginnersGraphic Design Crash Course for beginners
Graphic Design Crash Course for beginners
e20449
 
2024 RoOUG Security model for the cloud.pptx
2024 RoOUG Security model for the cloud.pptx2024 RoOUG Security model for the cloud.pptx
2024 RoOUG Security model for the cloud.pptx
Georgi Kodinov
 
Field Employee Tracking System| MiTrack App| Best Employee Tracking Solution|...
Field Employee Tracking System| MiTrack App| Best Employee Tracking Solution|...Field Employee Tracking System| MiTrack App| Best Employee Tracking Solution|...
Field Employee Tracking System| MiTrack App| Best Employee Tracking Solution|...
informapgpstrackings
 
GlobusWorld 2024 Opening Keynote session
GlobusWorld 2024 Opening Keynote sessionGlobusWorld 2024 Opening Keynote session
GlobusWorld 2024 Opening Keynote session
Globus
 
Navigating the Metaverse: A Journey into Virtual Evolution"
Navigating the Metaverse: A Journey into Virtual Evolution"Navigating the Metaverse: A Journey into Virtual Evolution"
Navigating the Metaverse: A Journey into Virtual Evolution"
Donna Lenk
 
Large Language Models and the End of Programming
Large Language Models and the End of ProgrammingLarge Language Models and the End of Programming
Large Language Models and the End of Programming
Matt Welsh
 
RISE with SAP and Journey to the Intelligent Enterprise
RISE with SAP and Journey to the Intelligent EnterpriseRISE with SAP and Journey to the Intelligent Enterprise
RISE with SAP and Journey to the Intelligent Enterprise
Srikant77
 
Accelerate Enterprise Software Engineering with Platformless
Accelerate Enterprise Software Engineering with PlatformlessAccelerate Enterprise Software Engineering with Platformless
Accelerate Enterprise Software Engineering with Platformless
WSO2
 
SOCRadar Research Team: Latest Activities of IntelBroker
SOCRadar Research Team: Latest Activities of IntelBrokerSOCRadar Research Team: Latest Activities of IntelBroker
SOCRadar Research Team: Latest Activities of IntelBroker
SOCRadar
 
Lecture 1 Introduction to games development
Lecture 1 Introduction to games developmentLecture 1 Introduction to games development
Lecture 1 Introduction to games development
abdulrafaychaudhry
 
A Comprehensive Look at Generative AI in Retail App Testing.pdf
A Comprehensive Look at Generative AI in Retail App Testing.pdfA Comprehensive Look at Generative AI in Retail App Testing.pdf
A Comprehensive Look at Generative AI in Retail App Testing.pdf
kalichargn70th171
 
Enhancing Project Management Efficiency_ Leveraging AI Tools like ChatGPT.pdf
Enhancing Project Management Efficiency_ Leveraging AI Tools like ChatGPT.pdfEnhancing Project Management Efficiency_ Leveraging AI Tools like ChatGPT.pdf
Enhancing Project Management Efficiency_ Leveraging AI Tools like ChatGPT.pdf
Jay Das
 
Exploring Innovations in Data Repository Solutions - Insights from the U.S. G...
Exploring Innovations in Data Repository Solutions - Insights from the U.S. G...Exploring Innovations in Data Repository Solutions - Insights from the U.S. G...
Exploring Innovations in Data Repository Solutions - Insights from the U.S. G...
Globus
 
Corporate Management | Session 3 of 3 | Tendenci AMS
Corporate Management | Session 3 of 3 | Tendenci AMSCorporate Management | Session 3 of 3 | Tendenci AMS
Corporate Management | Session 3 of 3 | Tendenci AMS
Tendenci - The Open Source AMS (Association Management Software)
 

Recently uploaded (20)

Gamify Your Mind; The Secret Sauce to Delivering Success, Continuously Improv...
Gamify Your Mind; The Secret Sauce to Delivering Success, Continuously Improv...Gamify Your Mind; The Secret Sauce to Delivering Success, Continuously Improv...
Gamify Your Mind; The Secret Sauce to Delivering Success, Continuously Improv...
 
Custom Healthcare Software for Managing Chronic Conditions and Remote Patient...
Custom Healthcare Software for Managing Chronic Conditions and Remote Patient...Custom Healthcare Software for Managing Chronic Conditions and Remote Patient...
Custom Healthcare Software for Managing Chronic Conditions and Remote Patient...
 
Vitthal Shirke Microservices Resume Montevideo
Vitthal Shirke Microservices Resume MontevideoVitthal Shirke Microservices Resume Montevideo
Vitthal Shirke Microservices Resume Montevideo
 
How Recreation Management Software Can Streamline Your Operations.pptx
How Recreation Management Software Can Streamline Your Operations.pptxHow Recreation Management Software Can Streamline Your Operations.pptx
How Recreation Management Software Can Streamline Your Operations.pptx
 
Beyond Event Sourcing - Embracing CRUD for Wix Platform - Java.IL
Beyond Event Sourcing - Embracing CRUD for Wix Platform - Java.ILBeyond Event Sourcing - Embracing CRUD for Wix Platform - Java.IL
Beyond Event Sourcing - Embracing CRUD for Wix Platform - Java.IL
 
Cracking the code review at SpringIO 2024
Cracking the code review at SpringIO 2024Cracking the code review at SpringIO 2024
Cracking the code review at SpringIO 2024
 
Graphic Design Crash Course for beginners
Graphic Design Crash Course for beginnersGraphic Design Crash Course for beginners
Graphic Design Crash Course for beginners
 
2024 RoOUG Security model for the cloud.pptx
2024 RoOUG Security model for the cloud.pptx2024 RoOUG Security model for the cloud.pptx
2024 RoOUG Security model for the cloud.pptx
 
Field Employee Tracking System| MiTrack App| Best Employee Tracking Solution|...
Field Employee Tracking System| MiTrack App| Best Employee Tracking Solution|...Field Employee Tracking System| MiTrack App| Best Employee Tracking Solution|...
Field Employee Tracking System| MiTrack App| Best Employee Tracking Solution|...
 
GlobusWorld 2024 Opening Keynote session
GlobusWorld 2024 Opening Keynote sessionGlobusWorld 2024 Opening Keynote session
GlobusWorld 2024 Opening Keynote session
 
Navigating the Metaverse: A Journey into Virtual Evolution"
Navigating the Metaverse: A Journey into Virtual Evolution"Navigating the Metaverse: A Journey into Virtual Evolution"
Navigating the Metaverse: A Journey into Virtual Evolution"
 
Large Language Models and the End of Programming
Large Language Models and the End of ProgrammingLarge Language Models and the End of Programming
Large Language Models and the End of Programming
 
RISE with SAP and Journey to the Intelligent Enterprise
RISE with SAP and Journey to the Intelligent EnterpriseRISE with SAP and Journey to the Intelligent Enterprise
RISE with SAP and Journey to the Intelligent Enterprise
 
Accelerate Enterprise Software Engineering with Platformless
Accelerate Enterprise Software Engineering with PlatformlessAccelerate Enterprise Software Engineering with Platformless
Accelerate Enterprise Software Engineering with Platformless
 
SOCRadar Research Team: Latest Activities of IntelBroker
SOCRadar Research Team: Latest Activities of IntelBrokerSOCRadar Research Team: Latest Activities of IntelBroker
SOCRadar Research Team: Latest Activities of IntelBroker
 
Lecture 1 Introduction to games development
Lecture 1 Introduction to games developmentLecture 1 Introduction to games development
Lecture 1 Introduction to games development
 
A Comprehensive Look at Generative AI in Retail App Testing.pdf
A Comprehensive Look at Generative AI in Retail App Testing.pdfA Comprehensive Look at Generative AI in Retail App Testing.pdf
A Comprehensive Look at Generative AI in Retail App Testing.pdf
 
Enhancing Project Management Efficiency_ Leveraging AI Tools like ChatGPT.pdf
Enhancing Project Management Efficiency_ Leveraging AI Tools like ChatGPT.pdfEnhancing Project Management Efficiency_ Leveraging AI Tools like ChatGPT.pdf
Enhancing Project Management Efficiency_ Leveraging AI Tools like ChatGPT.pdf
 
Exploring Innovations in Data Repository Solutions - Insights from the U.S. G...
Exploring Innovations in Data Repository Solutions - Insights from the U.S. G...Exploring Innovations in Data Repository Solutions - Insights from the U.S. G...
Exploring Innovations in Data Repository Solutions - Insights from the U.S. G...
 
Corporate Management | Session 3 of 3 | Tendenci AMS
Corporate Management | Session 3 of 3 | Tendenci AMSCorporate Management | Session 3 of 3 | Tendenci AMS
Corporate Management | Session 3 of 3 | Tendenci AMS
 

JavaOne 2016: Code Generation with JavaCompiler for Fun, Speed and Business Profit

  • 1. Medallia © Copyright 2016. Confidential. 1 Code Generation with JavaCompiler for Fun, Speed, and Business Profit Thorvald Natvig and Juan Cruz Nores
  • 2. Medallia © Copyright 2015. 2 At Medallia, we collect, analyze, and display terabytes of structured & unstructured feedback for our multibillion dollar clients in real time. And what’s more: we have a lot of fun doing it. Thorvald - Since 2010, growing from 70 to 1200 employees JC - First team in Argentina office, 2011 Who we are Hi, we’re JC & Thorvald @ Medallia
  • 3. Medallia © Copyright 2016. Confidential. 3 How to run an analytics engine at 30x speed 1/30th the cost Optimize for maximum performance with minimum engineering time All code shown today is on GitHub Includes bootstrap framework to do this yourself! What’s this all about? Fast Code in Short Time
  • 4. Medallia © Copyright 2016. Confidential. 4 AGENDA 1 2 3 4 5 6 Basics of CodeGen Problem and Java Solution CodeGen Learnings and Challenges Demo! “What’s next?”
  • 5. Medallia © Copyright 2016. Confidential. 5 Two ways to generate code: Method A: Use Java ASM and generate byte-code You spend most of the time writing a compiler Method B: Use Java Compiler to generate byte-code Someone else wrote the compiler Crash Course in Code Generation Don’t write a compiler
  • 6. Medallia © Copyright 2016. Confidential. 6 Crash Course in Code Generation Field f = Fields.get("age"); int min = 20; int max = 99; long sum = records.stream() .filter(x -> x.getValue(field) > min) .filter(x -> x.getValue(field) < max) .map(x -> x.getValue(field)) .mapToInt(x -> x) .sum();
  • 7. Medallia © Copyright 2016. Confidential. 7 Autoboxing and generics in general Stream constructs Function call to get value Spend most of the time in “streaming”, not in “computing” Problems!
  • 8. Medallia © Copyright 2016. Confidential. 8 // Assuming the field “age” is column 3 in the datastore... long generated(int [][] records) { long sum = 0; for (int i = 0; i < 88737273; ++i) { int fieldVar1 = records[3][i]; if (fieldVar1 > 20 && fieldVar1 < 99) sum += fieldVar1; } return sum; } Transformed code
  • 9. Medallia © Copyright 2016. Confidential. 9 Generate Java code as a String Invoke Java compiler in memory Load generated class and instantiate an object Call function How to guide “Somewhat faster”
  • 10. Medallia © Copyright 2016. Confidential. 10 We live in the real world Engineering time costs $$$; salary + lost opportunities Often cheaper to buy hardware than spend time to optimize Only apply this level of optimization if the saved server cost greatly outweighs the engineering cost. When should you do this? Optimize for Total Cost
  • 11. Medallia © Copyright 2016. Confidential. 11 AGENDA 1 2 3 4 5 6 Basics of CodeGen Problem and Java Solution CodeGen Learnings and Challenges Demo! “What’s next?”
  • 12. Medallia © Copyright 2016. Confidential. 12 An in-memory query engine Data is a segmented 2D table, each segment an int[][] We want to be able to execute queries such as: newQuery() .filter(field("a").in(1, 2, 3).or(field("b").is(3))) .aggregate(statsAggregate("ltr")) This is roughly equivalent to: SELECT AVG(ltr) FROM data WHERE a IN (1, 2, 3) OR b = 3 Problem
  • 13. Medallia © Copyright 2016. Confidential. 13 Query Execution b ltr 1 10 3 7 Filter passes? Aggregate no yesa 5 2
  • 14. Medallia © Copyright 2016. Confidential. 14 newQuery() .filter(field("a").in(1, 2, 3).or(field("b").is(3))) .aggregate(statsAggregate("ltr")) Pure Java OR “a” in [1,2,3] “b” in [3]
  • 15. Medallia © Copyright 2016. Confidential. 15 expression.visit(new ExprVisitor<Boolean>() { public Boolean visit(AndExpr andExpr) { return andExpr.getLeft().visit(this) && andExpr.getRight().visit(this); } public Boolean visit(InExpr inExpr) { /* ommitted */ } public Boolean visit(OrExpr orExpr) { return orExpr.getLeft().visit(this) || orExpr.getRight().visit(this); } /* other nodes */ }); Pure Java
  • 16. Medallia © Copyright 2016. Confidential. 16 Simple query: newQuery() .filter(field("a").in(1, 2, 3).or(field("b").is(3))) .aggregate(statsAggregate("ltr")) Complex query: newQuery() .filter(field("a").in(1, 2, 3, 5).or(field("b").is(3))) .filter(field("c").in(3, 5, 8, 1, 2).or(field("d").in(1,3,4))) .filter(not(field("e").in(2, 5, 8,10,12,13,14,15,17)).or(field("f").in(1,4,2))) .aggregate(statsAggregate("ltr")) 1M rows, split in 50k row segments (avoid large allocations) About the benchmarks
  • 17. Medallia © Copyright 2016. Confidential. 17 We actually built this And ran some benchmarks on it: Benchmark Mode Cnt Score Error Units InterpretedQueryBenchmark.complexQuery thrpt 6 14.453 ± 5.557 ops/s InterpretedQueryBenchmark.simpleQuery thrpt 6 46.057 ± 2.227 ops/s Pure Java Benchmark early+often
  • 18. Medallia © Copyright 2016. Confidential. 18 Idea: Reduce unnecessary per-traversal operations by using lambdas and their closures It also reduces overall number of method calls Take advantage of the massive optimizations implemented in HotSpot to support Streams and lambdas (invokedynamic) Optimized Pure Java
  • 19. Medallia © Copyright 2016. Confidential. 19 @FunctionalInterface interface Filter { boolean eval(Segment segment, int row); } public Filter visit(AndExpr andExpr) { Filter left = andExpr.getLeft().visit(this); Filter right = andExpr.getRight().visit(this); return (segment, row) -> left.eval(segment, row) && right.eval(segment, row); } Optimized Pure Java
  • 20. Medallia © Copyright 2016. Confidential. 20 public Filter visit(OrExpr orExpr) { Filter left = orExpr.getLeft().visit(this); Filter right = orExpr.getRight().visit(this); return (segment, row) -> left.eval(segment, row) && right.eval(segment, row); } public Filter visit(ConstantExpr constantExpr) { boolean val = constantExpr.value; return (segment, row) -> val; } Optimized Pure Java
  • 21. Medallia © Copyright 2016. Confidential. 21 public Filter visit(InExpr inExpr) { final int[] values = inExpr.getValues(); final int column = dataSet.getFieldByName(inExpr.getFieldName()).getColumn(); return (segment, row) -> { int fieldVal = segment.rawData[column][row]; for (int value : values) { if (value == fieldVal) return true; } return false; }; } Optimized Pure Java
  • 22. Medallia © Copyright 2016. Confidential. 22 So we ran some benchmarks on this too: Benchmark Mode Cnt Score Error Units StreamQueryBenchmark.complexQuery thrpt 6 33.046 ± 2.625 ops/s StreamQueryBenchmark.simpleQuery thrpt 6 124.077 ± 7.449 ops/s ~3X improvement on simple queries ~2X improvement on complex ones Optimized Pure Java
  • 23. Medallia © Copyright 2016. Confidential. 23 Results
  • 24. Medallia © Copyright 2016. Confidential. 24 AGENDA 1 2 3 4 5 6 Basics of CodeGen Problem and Java Solution CodeGen Learnings and Challenges Demo! “What’s next?”
  • 25. Medallia © Copyright 2016. Confidential. 25 Query execution boils down to: “iterate over every record, if it matches, aggregate” This implies a simple query structure: for (int i = 0; i < numRecords; i++) { if (/* record matches */) { /* aggregate */ } } Only the filter and the aggregate depend on the query CodeGen
  • 26. Medallia © Copyright 2016. Confidential. 26 cg.print(query.buildExpressionTree().visit(new ExprVisitor<String>() { public String visit(AndExpr andExpr) { return "(" +andExpr.getLeft().visit(this) +" && "+ andExpr.getRight().visit(this) + ")"; } public String visit(InExpr inExpr) { FieldDefinition field = dataSet.getFieldByName(inExpr.getFieldName()); return "(" + IntStream.of(inExpr.getValues()) .mapToObj(v -> String.format("rawData[%d][row] == %dL", field.getColumn(), v)) .reduce((a,b) -> a + " || " + b) .orElseThrow(() -> new RuntimeException("empty filter")) + ")"; } public String visit(NotExpr notExpr) { "!" + notExpr.getTarget().visit(this); } public String visit(OrExpr orExpr) { return "(" +orExpr.getLeft().visit(this) + " || " + orExpr.getRight().visit(this) + ")"; } public String visit(ConstantExpr constantExpr) { return String.valueOf(constantExpr.value); } })); Naive CodeGen
  • 27. Medallia © Copyright 2016. Confidential. 27 public void process(Segment segment) { int[][] rawData = segment.rawData; int nRows = rawData[0].length; FieldStats result$1 = (FieldStats)this.result; for (int row = 0; row < nRows; row++) { if ((rawData[0][row] == 1L || rawData[0][row] == 2L || rawData[0][row] == 3L) || (rawData[1][row] == 3L)) { result$1.count++; result$1.sum += rawData[6][row]; } } } Naive CodeGen
  • 28. Medallia © Copyright 2016. Confidential. 28 Benchmark Mode Cnt Score Error Units CompiledQuery.complexQuery thrpt 6 72.509 ± 13.526 ops/s CompiledQuery.simpleQuery thrpt 6 208.281 ± 11.335 ops/s ~4X improvement on simple queries (over the simple interpreter) ~5X improvement on complex ones Results
  • 29. Medallia © Copyright 2016. Confidential. 29 Results
  • 30. Medallia © Copyright 2016. Confidential. 30 Higher level transforms extract common subexpressions order filters to maximize the chance of rejecting a filter ... many of these apply also to the interpreter Low level transforms branch reduction perfect hashing ... Optimizing Your CodeGen
  • 31. Medallia © Copyright 2016. Confidential. 31 General strategy: instead of a set.contains() or set of ‘==’ comparisons Less than 3 values: a or b or c Value-range <= 64: reverse inverted bitmask. Value-range <= 1024: array of reverse inverted bitmask. Otherwise: Generated Perfect Hash Branch Reduction
  • 32. Medallia © Copyright 2016. Confidential. 32 Branch reduction 1 0 0 0 0 0 0 0 >>> test-val 0 1 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 1 1: 3: 4: 7: 0 1 0 1 1 0 0 1mask: bitwise or field("a") .in(1, 3, 4, 7)
  • 33. Medallia © Copyright 2016. Confidential. 33 Evaluation 1: 2: 0 1 0 1 1 0 0 1( field("a") .in(1, 3, 4, 7) << fieldVal ) < 0 01 0 1 1 0 0 1 00 1 1 0 0 1 0 Field Value ✅ ❌ = -78 = 100
  • 34. Medallia © Copyright 2016. Confidential. 34 newQuery() .filter(field("a").in(1, 2, 3, 9).or(field("b").is(3))) .aggregate(statsAggregate("ltr")); public void process(Segment segment) { int[][] rawData = segment.rawData; int nRows = rawData[0].length; FieldStats result$1 = (FieldStats)this.result; for (int row = 0; row < nRows; row++) { if (((0x7040000000000000L << rawData[0][row]) < 0 || (rawData[1][row] == 3L))) { result$1.count++; result$1.sum += rawData[2][row]; } } } Variant Code Generation
  • 35. Medallia © Copyright 2016. Confidential. 35 protected String generateInExpr(JavaCodeGenerator cg, InExpr inExpr) { final FieldDefinition fieldDef = dataSet.getFieldByName(inExpr.getFieldName()); final FieldSpec fieldSpec = fieldDef.getFieldSpec(); final int numValues = fieldSpec.getBound() - fieldSpec.getOrigin(); final int[] inValues = inExpr.getValues(); if (inValues.length > 3 && numValues < 64) { long mask = 0; for (int value : inValues) { mask |= 0x8000_0000_0000_0000L >>> (value - fieldSpec.getOrigin()); } if (fieldSpec.getOrigin() == 0) { return String.format("(0x%xL << rawData[%d][row]) < 0", mask, fieldDef.getColumn()); } else { return String.format("(0x%xL << (rawData[%d][row]-%dL)) < 0", mask, fieldDef.getColumn(), fieldSpec.getOrigin()); } } // Other cases, fall back to the naive one return super.generateInExpr(cg, inExpr); } Variant Code Generation
  • 36. Medallia © Copyright 2016. Confidential. 36 Benchmark Mode Cnt Score Error Units VariantQueryBenchmark.complexQuery thrpt 6 88.972 ± 2.206 ops/s VariantQueryBenchmark.simpleQuery thrpt 6 210.281 ± 8.007 ops/s about the same on simple queries (over the naive compiler) ~20% improvement on complex ones Results
  • 37. Medallia © Copyright 2016. Confidential. 37 Results
  • 38. Medallia © Copyright 2016. Confidential. 38 AGENDA 1 2 3 4 5 6 Basics of CodeGen Problem and Java Solution CodeGen Learnings and Challenges Demo! “What’s next?”
  • 39. Medallia © Copyright 2016. Confidential. 39 public void process(com.medallia.data.Segment); Code: // Save Segment.rawData into a local variable (var 2) 0: aload_1 1: getfield #3 4: astore_2 // get rawData[0].length and store it // in a local variable (var 3) 5: aload_2 6: iconst_0 7: aaload 8: arraylength 9: istore_3 // cast this.result into a FieldStats object and store it in a variable (var 4) 10: aload_0 11: getfield #2 // Field result:Ljava/lang/Object; 14: checkcast #4 // class FieldStats 17: astore 4 Why not do bytecode?
  • 40. Medallia © Copyright 2016. Confidential. 40 // Begin the loop // set i = 0 (var 5) 19: iconst_0 20: istore 5 // if i >= (var 3) -- number of rows // jump to end the loop (jump to instr 113) 22: iload 5 24: iload_3 25: if_icmpge 113 // rawData[0][i] == 1 goto 78 28: aload_2 29: iconst_0 30: aaload 31: iload 5 33: laload 34: lconst_1 35: lcmp 36: ifeq 78 // rawData[0][i] == 2 goto 78 … (more conditions) Why not do bytecode? … (more conditions) // fieldStats (var 4).count ++ 78: aload 4 80: dup 81: getfield #9 // Field FieldStats.count:J 84: lconst_1 85: ladd 86: putfield #9 // Field FieldStats.count:J // fieldStats (var 4).sum += rawData[6][i] 89: aload 4 91: dup 92: getfield #10 // Field FieldStats.sum:D 95: aload_2 96: bipush 6 98: aaload 99: iload 5 101: laload 102: l2d 103: dadd 104: putfield #10 // Field FieldStats.sum:D // i++ (var 5), jump to 22 (loop start) 107: iinc 5, 1 110: goto 22 113: return }
  • 41. Medallia © Copyright 2016. Confidential. 41 Javac is designed as a command line tool but… API in javax.tools! For the basic case we have to deal with three entities: Source files (input) Class files (output) Classpath File operations are abstracted behind JavaFileManager Compiling in-memory
  • 42. Medallia © Copyright 2016. Confidential. 42 Be careful with multithreading Cache warmup is the most time consuming part of compilation Simple strategy: Keep a JavaCompiler and a StandardJavaFileManager in a thread local variable Use a fixed size thread pool to constrain memory usage Compiling in-memory
  • 43. Medallia © Copyright 2016. Confidential. 43 Classloading The simplest strategy is to use one class per ClassLoader: public static <T> Class<? extends T> classFromBytes( final Class<T> baseClass, final String name, final byte[] bytecode) { return new ClassLoader(baseClass.getClassLoader()) { Class<? extends T> c = defineClass(name, bytecode, 0, bytecode.length) .asSubclass(baseClass); }.c; }
  • 44. Medallia © Copyright 2016. Confidential. 44 Pros: Easy to implement Memory reclamation is easy (each class/classloader pair is independent) Cons: Metaspace chunks are tied to a classloader → wasted metaspace Constrained to generating a single class Classloading
  • 45. Medallia © Copyright 2016. Confidential. 45 Most Java programs are fairly static JVM needs to warm up new code Interpreter C1 (-client compiler): fast compilation C2 (-server compiler): 20%-30% faster code for some workloads Dynamic class loading breaks some assumptions code size increases over application run time compiled code size does too: HotSpot CodeCache Classloading
  • 46. Medallia © Copyright 2016. Confidential. 46 HotSpot stores native code in its code cache You can run out of it If you do, the compilers are disabled "CodeCache is full. Compiler has been disabled" Some JVM options to deal with it: -XX:InitialCodeCacheSize -XX:ReservedCodeCacheSize -XX:+UseCodeCacheFlushing CodeCache
  • 47. Medallia © Copyright 2016. Confidential. 47 AGENDA 1 2 3 4 5 6 Basics of CodeGen Problem and Java Solution CodeGen Learnings and Challenges Demo! “What’s next?”
  • 48. Medallia © Copyright 2016. Confidential. 48 Demo
  • 49. Medallia © Copyright 2016. Confidential. 49 AGENDA 1 2 3 4 5 6 Basics of CodeGen Problem and Java Solution CodeGen Learnings and Challenges Demo! “What’s next?”
  • 50. Medallia © Copyright 2016. Confidential. 50 As in x86-64 assembly. And yes, YES WE ARE. We’re just one step away from ASM
  • 51. Medallia © Copyright 2016. Confidential. 51 Clang as a library Compile in-memory and execute C++ code Using medallia/unsafe (open source!) Java↔C++ argument marshalling Implement native methods on-the-fly! Generating C++ on-the-fly
  • 52. Medallia © Copyright 2016. Confidential. 52 #include <jni.h> /* omitted - initialization of field constants */ void process(JNIEnv* env, jobject self, jobject segment) { jint* rawData[cols]; /* omitted - get raw data arrays */ jdouble sum = 0; jlong count = 0; for (int row = 0; row < (int)nRows; row++) { if (((rawData[0][row] == 1L || rawData[0][row] == 2L || rawData[0][row] == 3L) || (rawData[1][row] == 3L))) { count++; sum += rawData[6][row]; } } /* omitted - release raw data arrays */ jobject result = env->GetObjectField(self, resultFld); env->SetLongField(result, countFld, env->GetLongField(result, countFld) + count); env->SetDoubleField(result, sumFld, env->GetDoubleField(result, sumFld) + sum); } C++ query
  • 53. Medallia © Copyright 2016. Confidential. 53 Benchmark Mode Cnt Score Error Units Unsafe.complexQuery thrpt 6 97.135 ± 4.905 ops/s Unsafe.simpleQuery thrpt 6 251.735 ± 14.856 ops/s ~20% improvement on simple queries (over the variant compiler) ~35% improvement on complex ones C++ query
  • 54. Medallia © Copyright 2016. Confidential. 54 Results
  • 55. Medallia © Copyright 2016. Confidential. 55 Java can now segfault. Using codegen limits probability of “incident” Not recommended. But fun. C++ violates everything Java
  • 56. Medallia © Copyright 2016. Confidential. 56 CodeGen is easy (and also fun) Focus on generating String code Faster to write Just as fast to execute (and often faster) Easy to debug Spend your time wisely Bottom Line
  • 57. Medallia © Copyright 2016. Confidential. 57 Code for this talk: https://github.com/medallia/javaone2016 Clang as a library: https://github.com/medallia/unsafe Thank you!