SlideShare a Scribd company logo
GraalVM: Fast,
Polyglot, Native
21.11.2018 // CODEMOTION BERLIN
Jan Stępień
@janstepien
janstepien.com
JAN STĘPIEŃ
Senior Consultant
jan.stepien@innoq.com
Functional Programming
Property-Based Testing
Architecture and Development
Some background
Ahead-of-time compilation
*.java *.clj *.scala
*.class
Ahead-of-time compilation
*.class
Just-in-time compilation
Native machine code
HotSpot
JIT compiling since 1999
JEP 243
JVM Compiler Interface
JD
K
9
Graal
A compiler written in Java
graalvm.org
Three main target groups
JVM engineers
Authors of languages
Programmers and end users
Architecture
Truffle
TruffleRuby
GraalVM
JVMCI
GraalJVM
Three main target groups
JVM engineers
Authors of languages
Programmers and end users
Polyglot VM and tooling
Faster execution
Native compilation
Programmers and end users
Native Java
Jan Stępień - GraalVM: Fast, Polyglot, Native - Codemotion Berlin 2018
public class HelloWorld {
public static void main(String[] args) {
System.out.println("👋 Berlin");
}
}
$ time java HelloWorld
👋 Berlin
0.14 real 0.13 user 0.03 sys
29M maximum resident set size
$ native-image HelloWorld
classlist: 3,196.20 ms
⋮
image: 1,693.59 ms
write: 472.40 ms
[total]: 44,197.16 ms
$ time ./HelloWorld
👋 Berlin
0.00 real 0.00 user 0.00 sys
4M maximum resident set size
Jan Stępień - GraalVM: Fast, Polyglot, Native - Codemotion Berlin 2018
Ahead-of-time
compilation
Just-in-time
compilation
Slower startup
Higher top speed
High memory usage
Faster startup
Lower top speed
Low memory usage
Native Clojure
$ docker inspect ubuntu 
| jq .[0].Size
(ns pprintin.main
(:require [clojure.pprint :refer [pprint]])
(:gen-class))
(defn -main [& path]
(-> (read *in*)
(get-in (mapv read-string path))
pprint))
$ echo {:a [5 3]} 
| time java -jar pprint.jar :a 1
3
1.51 real
112MB maximum resident set size
$ echo {:a [5 3]} 
| java -XX:TieredStopAtLevel=1 
-jar pprint.jar :a 1
3
1.06 real
96MB maximum resident set size
$ echo {:a [5 3]} 
| time lumo pprint.cljs :a 1
3
0.56 real
128MB maximum resident set size
$ native-image --no-server 
--static -jar pprint.jar
classlist: 3,596.11 ms
(...)
image: 4,671.96 ms
write: 14,763.97 ms
[total]: 122,614.21 ms
$ echo {:a [5 3]} 
| time ./pprint :a 1
3
0.01 real
12MB maximum resident set size
Time Memory
JVM 1.10 s 100 MB
JS 0.60 s 130 MB
Native 0.01 s 12 MB
Command line utilities
(ns json2edn.core
(:require [clojure.data.json :as json]))
(defn -main []
(->> (repeatedly #(json/read *in*
:key-fn keyword
:eof-error? false
:eof-value ::eof))
(take-while #(not= ::eof %))
(run! prn)))
;; See also Taylor Wood’s piece at
;; blog.taylorwood.io/2018/05/02/graal-clojure
$ cat package.json | time json2edn
{:description "Check if a value is an object",
:engines {:node ">=0.10.0"}, :license "MIT",
:repository "sindresorhus/is-obj",
:name "is-obj", :scripts {:test "xo && ava"},
:keywords ["obj" "object" "is" "check" "test"
"type"], :author {:name "Sindre Sorhus",
:email "sindresorhus@gmail.com", :url
"sindresorhus.com"}, :files ["index.js"],
:version “1.0.1"}
0.01 real
10MB maximum resident set size
Jan Stępień - GraalVM: Fast, Polyglot, Native - Codemotion Berlin 2018
(require '[spec-provider.provider :as sp])
(def inferred-specs
(sp/infer-specs
[{:a 8 :b "foo" :c :k}
{:a 10 :b "bar" :c "k"}
{:a 1 :b "baz" :c "k"}]
:toy/small-map))
(sp/pprint-specs inferred-specs 'toy ’s)
;; Results in the following being printed
(s/def ::c (s/or :keyword keyword? :string string?))
(s/def ::b string?)
(s/def ::a integer?)
(s/def ::small-map (s/keys :req-un [::a ::b ::c]))
(ns spec-provider.main
(:require [spec-provider.provider :as sp]
[clojure.string :as str]
[clojure.edn :as edn])
(:gen-class))
(defn -main
[spec-name]
(let [kw (as-keyword spec-name)
read-one (edn/read {:eof ::eof} *in*)
samples (sequence
(take-while (complement #{::eof}))
(repeatedly read-one))
specs (sp/infer-specs samples kw)]
(sp/pprint-specs specs (namespace kw) 's))))
Jan Stępień - GraalVM: Fast, Polyglot, Native - Codemotion Berlin 2018
$ cat node_modules/*/package.json 
| json2edn | spec-provider :node/package | zprint
;; ...
(s/def ::repository
(s/or :map (s/keys :req-un [::type ::url])
:simple string?))
(s/def ::npm string?)
(s/def ::node string?)
(s/def ::engines (s/keys :req-un [::node] :opt-un [::iojs ::npm]))
(s/def ::description string?)
(s/def ::package
(s/keys :req-un [::description ::name ::repository ::version]
:opt-un [::author ::bin ::browser ::bugs ::contributors
::dependencies ::devDependencies ::engines
::files ::homepage ::icon ::keywords ::license
::main ::maintainers ::optionalDependencies
::peerDependencies ::scripts]))
0.29 real
103MB maximum resident set size
A simple Clojure web app
$ curl -i http://localhost:8080/kv/city -X PUT -d val=Berlin
HTTP/1.1 201 Created
Content-Type: application/octet-stream
Content-Length: 8
Server: http-kit
Date: Mon, 03 Sep 2018 16:04:22 GMT
Berlin
$ curl -i http://localhost:8080/kv/city
HTTP/1.1 200 OK
Content-Type: application/octet-stream
Content-Length: 8
Server: http-kit
Date: Mon, 03 Sep 2018 16:04:27 GMT
Berlin
(ns webkv.main
(:require [org.httpkit.server :as http]
[ring.middleware.defaults
:refer [wrap-defaults
api-defaults]]
[bidi.ring :refer [make-handler]])
(:gen-class))
;; We want to be sure none of our calls relies
;; on reflection. Graal does not support them.
(set! *warn-on-reflection* 1)
;; This is where we store our data.
(def ^String tmpdir
(System/getProperty "java.io.tmpdir"))
;; That's how we find a file given a key.
;; Keys must match the given pattern.
(defn file [^String key]
{:pre [(re-matches #"^[A-Za-z-]+$" key)]}
(java.io.File. tmpdir key))
;; Here we handle GET requests. We just
;; read from a file.
(defn get-handler
[{:keys [params]}]
{:body (str (slurp (file (params :key))) "n")})
;; This is our PUT request handler. Given
;; a key and a value we write to a file.
(defn put-handler
[{:keys [params]}]
(let [val (params :val)]
(spit (file (params :key)) val)
{:body (str val "n") , :status 201}))
;; Here's the routing tree of our application.
;; We pick the handler depending on the HTTP
;; verb. On top of that we add an extra middle-
;; ware to parse data sent in requests.
(def handler
(-> ["/kv/" {[:key] {:get #'get-handler
:put #'put-handler}}]
(make-handler)
(wrap-defaults api-defaults)))
;; Finally, we've got all we need to expose
;; our handler over HTTP.
(defn -main []
(http/run-server handler
{:port 8080})
(println "🔥 http://localhost:8080"))
Docker images
FROM ubuntu AS BASE
RUN apt-get update
RUN apt-get install -yy curl leiningen build-essential zlib1g-dev
RUN cd /opt && curl -sL https://github.com/.../graalvm.tar.gz 
| tar -xzf -
ADD project.clj .
RUN lein deps
ADD src src
RUN lein uberjar
RUN /opt/graalvm-ce-1.0.0-rc5/bin/native-image 
-H:EnableURLProtocols=http --static --no-server 
-cp target/webkv-0.0.0-standalone.jar webkv.main
FROM scratch
COPY --from=BASE /webkv.main /
CMD ["/webkv.main"]
13
M
B
How Is That Even Possible
Time Memory
JVM 1.10 s 100 MB
JS 0.60 s 130 MB
Native 0.01 s 12 MB
Jan Stępień - GraalVM: Fast, Polyglot, Native - Codemotion Berlin 2018
static {
...
}
initialiser
Static
class
https://blog.ndk.io/clojure-compilation
Jan Stępień - GraalVM: Fast, Polyglot, Native - Codemotion Berlin 2018
GraalVM: Fast,
Polyglot, Native
Jan Stępień
@janstepien
janstepien.com
21.11.2018 // CODEMOTION BERLIN
This work is licensed under a Creative Commons Attribution-NonCommercial-ShareAlike 3.0 Unported License.
https://creativecommons.org/licenses/by-nc-sa/3.0/

More Related Content

What's hot (20)

PDF
服务框架: Thrift & PasteScript
Qiangning Hong
 
PDF
Introduction to reactive programming & ReactiveCocoa
Florent Pillet
 
KEY
PyCon AU 2012 - Debugging Live Python Web Applications
Graham Dumpleton
 
PDF
Spock: A Highly Logical Way To Test
Howard Lewis Ship
 
ZIP
Groovy and Grails in Action - Devoxx 2008 - University - Guillaume Laforge
Guillaume Laforge
 
PDF
Golang Performance : microbenchmarks, profilers, and a war story
Aerospike
 
PDF
Gradle in a Polyglot World
Schalk Cronjé
 
PDF
Job Queue in Golang
Bo-Yi Wu
 
PDF
Testing Backbone applications with Jasmine
Leon van der Grient
 
PDF
用 Go 語言打造多台機器 Scale 架構
Bo-Yi Wu
 
PDF
Exploring Clojurescript
Luke Donnet
 
PPTX
Node.js System: The Approach
Haci Murat Yaman
 
PDF
Node.js extensions in C++
Kenneth Geisshirt
 
PDF
Introducing Troy Scala IO 2016
Tamer Abdul-Radi
 
PDF
"ClojureScript journey: from little script, to CLI program, to AWS Lambda fun...
Julia Cherniak
 
PPTX
Exploring the Titanium CLI - Codestrong 2012
Chris Barber
 
PPTX
Large scale nlp using python's nltk on azure
cloudbeatsch
 
PDF
Natural Language Toolkit (NLTK), Basics
Prakash Pimpale
 
PPTX
Titanium 3.2 CLI - TiAppCamp2 - 11/2/2013
Chris Barber
 
PPTX
Behind modern concurrency primitives
Bartosz Sypytkowski
 
服务框架: Thrift & PasteScript
Qiangning Hong
 
Introduction to reactive programming & ReactiveCocoa
Florent Pillet
 
PyCon AU 2012 - Debugging Live Python Web Applications
Graham Dumpleton
 
Spock: A Highly Logical Way To Test
Howard Lewis Ship
 
Groovy and Grails in Action - Devoxx 2008 - University - Guillaume Laforge
Guillaume Laforge
 
Golang Performance : microbenchmarks, profilers, and a war story
Aerospike
 
Gradle in a Polyglot World
Schalk Cronjé
 
Job Queue in Golang
Bo-Yi Wu
 
Testing Backbone applications with Jasmine
Leon van der Grient
 
用 Go 語言打造多台機器 Scale 架構
Bo-Yi Wu
 
Exploring Clojurescript
Luke Donnet
 
Node.js System: The Approach
Haci Murat Yaman
 
Node.js extensions in C++
Kenneth Geisshirt
 
Introducing Troy Scala IO 2016
Tamer Abdul-Radi
 
"ClojureScript journey: from little script, to CLI program, to AWS Lambda fun...
Julia Cherniak
 
Exploring the Titanium CLI - Codestrong 2012
Chris Barber
 
Large scale nlp using python's nltk on azure
cloudbeatsch
 
Natural Language Toolkit (NLTK), Basics
Prakash Pimpale
 
Titanium 3.2 CLI - TiAppCamp2 - 11/2/2013
Chris Barber
 
Behind modern concurrency primitives
Bartosz Sypytkowski
 

Similar to Jan Stępień - GraalVM: Fast, Polyglot, Native - Codemotion Berlin 2018 (20)

PDF
Polyglot Applications with GraalVM
jexp
 
PDF
Adopting GraalVM - Scale by the Bay 2018
Petr Zapletal
 
PDF
GraalVM
Manfredi Giordano
 
PDF
GraalVM - OpenSlava 2019-10-18
Jorge Hidalgo
 
PDF
Graal and Truffle: Modularity and Separation of Concerns as Cornerstones for ...
Thomas Wuerthinger
 
PDF
GraalVM - MadridJUG 2019-10-22
Jorge Hidalgo
 
PDF
Javantura v4 - JVM++ The GraalVM - Martin Toshev
HUJAK - Hrvatska udruga Java korisnika / Croatian Java User Association
 
PDF
Polygot Java EE on the GraalVM
Ryan Cuprak
 
PPTX
JVM++: The Graal VM
Martin Toshev
 
PPTX
How and Why GraalVM is quickly becoming relevant for developers (ACEs@home - ...
Lucas Jellema
 
PDF
Graal Tutorial at CGO 2015 by Christian Wimmer
Thomas Wuerthinger
 
KEY
The Why and How of Scala at Twitter
Alex Payne
 
PDF
GraalVM - JBCNConf 2019-05-28
Jorge Hidalgo
 
PDF
Graalvm with Groovy and Kotlin - Greach 2019
Alberto De Ávila Hernández
 
PPTX
HOW AND WHY GRAALVM IS QUICKLY BECOMING RELEVANT FOR YOU
Lucas Jellema
 
PDF
Graalvm with Groovy and Kotlin - Madrid GUG 2019
Alberto De Ávila Hernández
 
PDF
Enter the gradle
Parameswari Ettiappan
 
PPTX
All you need to know about Spring Boot and GraalVM
Alina Yurenko
 
PDF
Gradle Introduction
Dmitry Buzdin
 
PDF
Gradleintroduction 111010130329-phpapp01
Tino Isnich
 
Polyglot Applications with GraalVM
jexp
 
Adopting GraalVM - Scale by the Bay 2018
Petr Zapletal
 
GraalVM - OpenSlava 2019-10-18
Jorge Hidalgo
 
Graal and Truffle: Modularity and Separation of Concerns as Cornerstones for ...
Thomas Wuerthinger
 
GraalVM - MadridJUG 2019-10-22
Jorge Hidalgo
 
Javantura v4 - JVM++ The GraalVM - Martin Toshev
HUJAK - Hrvatska udruga Java korisnika / Croatian Java User Association
 
Polygot Java EE on the GraalVM
Ryan Cuprak
 
JVM++: The Graal VM
Martin Toshev
 
How and Why GraalVM is quickly becoming relevant for developers (ACEs@home - ...
Lucas Jellema
 
Graal Tutorial at CGO 2015 by Christian Wimmer
Thomas Wuerthinger
 
The Why and How of Scala at Twitter
Alex Payne
 
GraalVM - JBCNConf 2019-05-28
Jorge Hidalgo
 
Graalvm with Groovy and Kotlin - Greach 2019
Alberto De Ávila Hernández
 
HOW AND WHY GRAALVM IS QUICKLY BECOMING RELEVANT FOR YOU
Lucas Jellema
 
Graalvm with Groovy and Kotlin - Madrid GUG 2019
Alberto De Ávila Hernández
 
Enter the gradle
Parameswari Ettiappan
 
All you need to know about Spring Boot and GraalVM
Alina Yurenko
 
Gradle Introduction
Dmitry Buzdin
 
Gradleintroduction 111010130329-phpapp01
Tino Isnich
 
Ad

More from Codemotion (20)

PDF
Fuzz-testing: A hacker's approach to making your code more secure | Pascal Ze...
Codemotion
 
PDF
Pompili - From hero to_zero: The FatalNoise neverending story
Codemotion
 
PPTX
Pastore - Commodore 65 - La storia
Codemotion
 
PPTX
Pennisi - Essere Richard Altwasser
Codemotion
 
PPTX
Michel Schudel - Let's build a blockchain... in 40 minutes! - Codemotion Amst...
Codemotion
 
PPTX
Richard Süselbeck - Building your own ride share app - Codemotion Amsterdam 2019
Codemotion
 
PPTX
Eward Driehuis - What we learned from 20.000 attacks - Codemotion Amsterdam 2019
Codemotion
 
PPTX
Francesco Baldassarri - Deliver Data at Scale - Codemotion Amsterdam 2019 -
Codemotion
 
PDF
Martin Förtsch, Thomas Endres - Stereoscopic Style Transfer AI - Codemotion A...
Codemotion
 
PDF
Melanie Rieback, Klaus Kursawe - Blockchain Security: Melting the "Silver Bul...
Codemotion
 
PDF
Angelo van der Sijpt - How well do you know your network stack? - Codemotion ...
Codemotion
 
PDF
Lars Wolff - Performance Testing for DevOps in the Cloud - Codemotion Amsterd...
Codemotion
 
PDF
Sascha Wolter - Conversational AI Demystified - Codemotion Amsterdam 2019
Codemotion
 
PDF
Michele Tonutti - Scaling is caring - Codemotion Amsterdam 2019
Codemotion
 
PPTX
Pat Hermens - From 100 to 1,000+ deployments a day - Codemotion Amsterdam 2019
Codemotion
 
PPTX
James Birnie - Using Many Worlds of Compute Power with Quantum - Codemotion A...
Codemotion
 
PDF
Don Goodman-Wilson - Chinese food, motor scooters, and open source developmen...
Codemotion
 
PDF
Pieter Omvlee - The story behind Sketch - Codemotion Amsterdam 2019
Codemotion
 
PDF
Dave Farley - Taking Back “Software Engineering” - Codemotion Amsterdam 2019
Codemotion
 
PDF
Joshua Hoffman - Should the CTO be Coding? - Codemotion Amsterdam 2019
Codemotion
 
Fuzz-testing: A hacker's approach to making your code more secure | Pascal Ze...
Codemotion
 
Pompili - From hero to_zero: The FatalNoise neverending story
Codemotion
 
Pastore - Commodore 65 - La storia
Codemotion
 
Pennisi - Essere Richard Altwasser
Codemotion
 
Michel Schudel - Let's build a blockchain... in 40 minutes! - Codemotion Amst...
Codemotion
 
Richard Süselbeck - Building your own ride share app - Codemotion Amsterdam 2019
Codemotion
 
Eward Driehuis - What we learned from 20.000 attacks - Codemotion Amsterdam 2019
Codemotion
 
Francesco Baldassarri - Deliver Data at Scale - Codemotion Amsterdam 2019 -
Codemotion
 
Martin Förtsch, Thomas Endres - Stereoscopic Style Transfer AI - Codemotion A...
Codemotion
 
Melanie Rieback, Klaus Kursawe - Blockchain Security: Melting the "Silver Bul...
Codemotion
 
Angelo van der Sijpt - How well do you know your network stack? - Codemotion ...
Codemotion
 
Lars Wolff - Performance Testing for DevOps in the Cloud - Codemotion Amsterd...
Codemotion
 
Sascha Wolter - Conversational AI Demystified - Codemotion Amsterdam 2019
Codemotion
 
Michele Tonutti - Scaling is caring - Codemotion Amsterdam 2019
Codemotion
 
Pat Hermens - From 100 to 1,000+ deployments a day - Codemotion Amsterdam 2019
Codemotion
 
James Birnie - Using Many Worlds of Compute Power with Quantum - Codemotion A...
Codemotion
 
Don Goodman-Wilson - Chinese food, motor scooters, and open source developmen...
Codemotion
 
Pieter Omvlee - The story behind Sketch - Codemotion Amsterdam 2019
Codemotion
 
Dave Farley - Taking Back “Software Engineering” - Codemotion Amsterdam 2019
Codemotion
 
Joshua Hoffman - Should the CTO be Coding? - Codemotion Amsterdam 2019
Codemotion
 
Ad

Recently uploaded (20)

PDF
How ETL Control Logic Keeps Your Pipelines Safe and Reliable.pdf
Stryv Solutions Pvt. Ltd.
 
PDF
Make GenAI investments go further with the Dell AI Factory
Principled Technologies
 
PDF
Market Insight : ETH Dominance Returns
CIFDAQ
 
PDF
MASTERDECK GRAPHSUMMIT SYDNEY (Public).pdf
Neo4j
 
PDF
A Strategic Analysis of the MVNO Wave in Emerging Markets.pdf
IPLOOK Networks
 
PPTX
AI Code Generation Risks (Ramkumar Dilli, CIO, Myridius)
Priyanka Aash
 
PDF
NewMind AI Weekly Chronicles – July’25, Week III
NewMind AI
 
PDF
Structs to JSON: How Go Powers REST APIs
Emily Achieng
 
PDF
Economic Impact of Data Centres to the Malaysian Economy
flintglobalapac
 
PDF
The Future of Artificial Intelligence (AI)
Mukul
 
PDF
Data_Analytics_vs_Data_Science_vs_BI_by_CA_Suvidha_Chaplot.pdf
CA Suvidha Chaplot
 
PDF
Trying to figure out MCP by actually building an app from scratch with open s...
Julien SIMON
 
PDF
How Open Source Changed My Career by abdelrahman ismail
a0m0rajab1
 
PPTX
Agile Chennai 18-19 July 2025 Ideathon | AI Powered Microfinance Literacy Gui...
AgileNetwork
 
PPTX
Agentic AI in Healthcare Driving the Next Wave of Digital Transformation
danielle hunter
 
PDF
RAT Builders - How to Catch Them All [DeepSec 2024]
malmoeb
 
PDF
Brief History of Internet - Early Days of Internet
sutharharshit158
 
PPTX
The Future of AI & Machine Learning.pptx
pritsen4700
 
PPTX
Introduction to Flutter by Ayush Desai.pptx
ayushdesai204
 
PPTX
AI and Robotics for Human Well-being.pptx
JAYMIN SUTHAR
 
How ETL Control Logic Keeps Your Pipelines Safe and Reliable.pdf
Stryv Solutions Pvt. Ltd.
 
Make GenAI investments go further with the Dell AI Factory
Principled Technologies
 
Market Insight : ETH Dominance Returns
CIFDAQ
 
MASTERDECK GRAPHSUMMIT SYDNEY (Public).pdf
Neo4j
 
A Strategic Analysis of the MVNO Wave in Emerging Markets.pdf
IPLOOK Networks
 
AI Code Generation Risks (Ramkumar Dilli, CIO, Myridius)
Priyanka Aash
 
NewMind AI Weekly Chronicles – July’25, Week III
NewMind AI
 
Structs to JSON: How Go Powers REST APIs
Emily Achieng
 
Economic Impact of Data Centres to the Malaysian Economy
flintglobalapac
 
The Future of Artificial Intelligence (AI)
Mukul
 
Data_Analytics_vs_Data_Science_vs_BI_by_CA_Suvidha_Chaplot.pdf
CA Suvidha Chaplot
 
Trying to figure out MCP by actually building an app from scratch with open s...
Julien SIMON
 
How Open Source Changed My Career by abdelrahman ismail
a0m0rajab1
 
Agile Chennai 18-19 July 2025 Ideathon | AI Powered Microfinance Literacy Gui...
AgileNetwork
 
Agentic AI in Healthcare Driving the Next Wave of Digital Transformation
danielle hunter
 
RAT Builders - How to Catch Them All [DeepSec 2024]
malmoeb
 
Brief History of Internet - Early Days of Internet
sutharharshit158
 
The Future of AI & Machine Learning.pptx
pritsen4700
 
Introduction to Flutter by Ayush Desai.pptx
ayushdesai204
 
AI and Robotics for Human Well-being.pptx
JAYMIN SUTHAR
 

Jan Stępień - GraalVM: Fast, Polyglot, Native - Codemotion Berlin 2018

  • 1. GraalVM: Fast, Polyglot, Native 21.11.2018 // CODEMOTION BERLIN Jan Stępień @janstepien janstepien.com
  • 2. JAN STĘPIEŃ Senior Consultant [email protected] Functional Programming Property-Based Testing Architecture and Development
  • 7. JEP 243 JVM Compiler Interface JD K 9
  • 10. Three main target groups JVM engineers Authors of languages Programmers and end users
  • 13. Three main target groups JVM engineers Authors of languages Programmers and end users
  • 14. Polyglot VM and tooling Faster execution Native compilation Programmers and end users
  • 17. public class HelloWorld { public static void main(String[] args) { System.out.println("👋 Berlin"); } }
  • 18. $ time java HelloWorld 👋 Berlin 0.14 real 0.13 user 0.03 sys 29M maximum resident set size
  • 19. $ native-image HelloWorld classlist: 3,196.20 ms ⋮ image: 1,693.59 ms write: 472.40 ms [total]: 44,197.16 ms
  • 20. $ time ./HelloWorld 👋 Berlin 0.00 real 0.00 user 0.00 sys 4M maximum resident set size
  • 22. Ahead-of-time compilation Just-in-time compilation Slower startup Higher top speed High memory usage Faster startup Lower top speed Low memory usage
  • 24. $ docker inspect ubuntu | jq .[0].Size
  • 25. (ns pprintin.main (:require [clojure.pprint :refer [pprint]]) (:gen-class)) (defn -main [& path] (-> (read *in*) (get-in (mapv read-string path)) pprint))
  • 26. $ echo {:a [5 3]} | time java -jar pprint.jar :a 1 3 1.51 real 112MB maximum resident set size
  • 27. $ echo {:a [5 3]} | java -XX:TieredStopAtLevel=1 -jar pprint.jar :a 1 3 1.06 real 96MB maximum resident set size
  • 28. $ echo {:a [5 3]} | time lumo pprint.cljs :a 1 3 0.56 real 128MB maximum resident set size
  • 29. $ native-image --no-server --static -jar pprint.jar classlist: 3,596.11 ms (...) image: 4,671.96 ms write: 14,763.97 ms [total]: 122,614.21 ms
  • 30. $ echo {:a [5 3]} | time ./pprint :a 1 3 0.01 real 12MB maximum resident set size
  • 31. Time Memory JVM 1.10 s 100 MB JS 0.60 s 130 MB Native 0.01 s 12 MB
  • 33. (ns json2edn.core (:require [clojure.data.json :as json])) (defn -main [] (->> (repeatedly #(json/read *in* :key-fn keyword :eof-error? false :eof-value ::eof)) (take-while #(not= ::eof %)) (run! prn))) ;; See also Taylor Wood’s piece at ;; blog.taylorwood.io/2018/05/02/graal-clojure
  • 34. $ cat package.json | time json2edn {:description "Check if a value is an object", :engines {:node ">=0.10.0"}, :license "MIT", :repository "sindresorhus/is-obj", :name "is-obj", :scripts {:test "xo && ava"}, :keywords ["obj" "object" "is" "check" "test" "type"], :author {:name "Sindre Sorhus", :email "[email protected]", :url "sindresorhus.com"}, :files ["index.js"], :version “1.0.1"} 0.01 real 10MB maximum resident set size
  • 36. (require '[spec-provider.provider :as sp]) (def inferred-specs (sp/infer-specs [{:a 8 :b "foo" :c :k} {:a 10 :b "bar" :c "k"} {:a 1 :b "baz" :c "k"}] :toy/small-map)) (sp/pprint-specs inferred-specs 'toy ’s) ;; Results in the following being printed (s/def ::c (s/or :keyword keyword? :string string?)) (s/def ::b string?) (s/def ::a integer?) (s/def ::small-map (s/keys :req-un [::a ::b ::c]))
  • 37. (ns spec-provider.main (:require [spec-provider.provider :as sp] [clojure.string :as str] [clojure.edn :as edn]) (:gen-class)) (defn -main [spec-name] (let [kw (as-keyword spec-name) read-one (edn/read {:eof ::eof} *in*) samples (sequence (take-while (complement #{::eof})) (repeatedly read-one)) specs (sp/infer-specs samples kw)] (sp/pprint-specs specs (namespace kw) 's))))
  • 39. $ cat node_modules/*/package.json | json2edn | spec-provider :node/package | zprint ;; ... (s/def ::repository (s/or :map (s/keys :req-un [::type ::url]) :simple string?)) (s/def ::npm string?) (s/def ::node string?) (s/def ::engines (s/keys :req-un [::node] :opt-un [::iojs ::npm])) (s/def ::description string?) (s/def ::package (s/keys :req-un [::description ::name ::repository ::version] :opt-un [::author ::bin ::browser ::bugs ::contributors ::dependencies ::devDependencies ::engines ::files ::homepage ::icon ::keywords ::license ::main ::maintainers ::optionalDependencies ::peerDependencies ::scripts])) 0.29 real 103MB maximum resident set size
  • 40. A simple Clojure web app
  • 41. $ curl -i http://localhost:8080/kv/city -X PUT -d val=Berlin HTTP/1.1 201 Created Content-Type: application/octet-stream Content-Length: 8 Server: http-kit Date: Mon, 03 Sep 2018 16:04:22 GMT Berlin $ curl -i http://localhost:8080/kv/city HTTP/1.1 200 OK Content-Type: application/octet-stream Content-Length: 8 Server: http-kit Date: Mon, 03 Sep 2018 16:04:27 GMT Berlin
  • 42. (ns webkv.main (:require [org.httpkit.server :as http] [ring.middleware.defaults :refer [wrap-defaults api-defaults]] [bidi.ring :refer [make-handler]]) (:gen-class)) ;; We want to be sure none of our calls relies ;; on reflection. Graal does not support them. (set! *warn-on-reflection* 1) ;; This is where we store our data. (def ^String tmpdir (System/getProperty "java.io.tmpdir")) ;; That's how we find a file given a key. ;; Keys must match the given pattern. (defn file [^String key] {:pre [(re-matches #"^[A-Za-z-]+$" key)]} (java.io.File. tmpdir key)) ;; Here we handle GET requests. We just ;; read from a file. (defn get-handler [{:keys [params]}] {:body (str (slurp (file (params :key))) "n")}) ;; This is our PUT request handler. Given ;; a key and a value we write to a file. (defn put-handler [{:keys [params]}] (let [val (params :val)] (spit (file (params :key)) val) {:body (str val "n") , :status 201})) ;; Here's the routing tree of our application. ;; We pick the handler depending on the HTTP ;; verb. On top of that we add an extra middle- ;; ware to parse data sent in requests. (def handler (-> ["/kv/" {[:key] {:get #'get-handler :put #'put-handler}}] (make-handler) (wrap-defaults api-defaults))) ;; Finally, we've got all we need to expose ;; our handler over HTTP. (defn -main [] (http/run-server handler {:port 8080}) (println "🔥 http://localhost:8080"))
  • 44. FROM ubuntu AS BASE RUN apt-get update RUN apt-get install -yy curl leiningen build-essential zlib1g-dev RUN cd /opt && curl -sL https://github.com/.../graalvm.tar.gz | tar -xzf - ADD project.clj . RUN lein deps ADD src src RUN lein uberjar RUN /opt/graalvm-ce-1.0.0-rc5/bin/native-image -H:EnableURLProtocols=http --static --no-server -cp target/webkv-0.0.0-standalone.jar webkv.main FROM scratch COPY --from=BASE /webkv.main / CMD ["/webkv.main"] 13 M B
  • 45. How Is That Even Possible
  • 46. Time Memory JVM 1.10 s 100 MB JS 0.60 s 130 MB Native 0.01 s 12 MB
  • 51. GraalVM: Fast, Polyglot, Native Jan Stępień @janstepien janstepien.com 21.11.2018 // CODEMOTION BERLIN
  • 52. This work is licensed under a Creative Commons Attribution-NonCommercial-ShareAlike 3.0 Unported License. https://creativecommons.org/licenses/by-nc-sa/3.0/