Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
Faster than C?
Search
Felix Geisendörfer
November 29, 2012
Programming
1
1.2k
Faster than C?
Presentation given at the Prague JS Usergroup.
Felix Geisendörfer
November 29, 2012
Tweet
Share
More Decks by Felix Geisendörfer
See All by Felix Geisendörfer
tus.io - Resumable File Uploads (Lightning Talk)
felixge
2
720
Programming flying robots with JavaScript
felixge
2
900
Programming flying robots with JavaScript
felixge
0
540
Programming an AR Drone Firmware with JS (de)
felixge
1
570
Flying robots over a 10.000 mile distance with JavaScript.
felixge
0
440
Faster than C?
felixge
1
570
The power of node.js (with quadcopters)
felixge
0
450
Faster than C?
felixge
0
370
Faster than C? Parsing binary data in JavaScript.
felixge
3
3.7k
Other Decks in Programming
See All in Programming
どうして僕の作ったクラスが手続き型と言われなきゃいけないんですか
akikogoto
1
120
Arm移行タイムアタック
qnighy
0
290
型付き API リクエストを実現するいくつかの手法とその選択 / Typed API Request
euxn23
8
2.2k
Jakarta EE meets AI
ivargrimstad
0
510
Macとオーディオ再生 2024/11/02
yusukeito
0
370
AWS IaCの注目アップデート 2024年10月版
konokenj
3
3.3k
CSC509 Lecture 11
javiergs
PRO
0
180
Content Security Policy入門 セキュリティ設定と 違反レポートのはじめ方 / Introduction to Content Security Policy Getting Started with Security Configuration and Violation Reporting
uskey512
1
520
as(型アサーション)を書く前にできること
marokanatani
8
2.6k
Less waste, more joy, and a lot more green: How Quarkus makes Java better
hollycummins
0
100
見せてあげますよ、「本物のLaravel批判」ってやつを。
77web
7
7.7k
ペアーズにおけるAmazon Bedrockを⽤いた障害対応⽀援 ⽣成AIツールの導⼊事例 @ 20241115配信AWSウェビナー登壇
fukubaka0825
6
1.8k
Featured
See All Featured
The Success of Rails: Ensuring Growth for the Next 100 Years
eileencodes
44
6.8k
Distributed Sagas: A Protocol for Coordinating Microservices
caitiem20
329
21k
Facilitating Awesome Meetings
lara
50
6.1k
Building a Scalable Design System with Sketch
lauravandoore
459
33k
The Invisible Side of Design
smashingmag
298
50k
Writing Fast Ruby
sferik
627
61k
ReactJS: Keep Simple. Everything can be a component!
pedronauck
665
120k
Measuring & Analyzing Core Web Vitals
bluesmoon
4
120
ピンチをチャンスに:未来をつくるプロダクトロードマップ #pmconf2020
aki_iinuma
109
49k
Bash Introduction
62gerente
608
210k
Adopting Sorbet at Scale
ufuk
73
9.1k
VelocityConf: Rendering Performance Case Studies
addyosmani
325
24k
Transcript
felixge Faster than C? Parsing binary data in JavaScript Felix
Geisendörfer
@felixge felixge Background 2005 - 2008 2008 - now 2009
- now
@felixge felixge The NodeCopter nodecopter.com
felixge This Talk
felixge JavaScript vs C
felixge Good vs Evil
felixge Good Parts vs Evil
felixge Bad Parts vs Evil
felixge Faster than C?
felixge No Sorry for the “title bait”
felixge As fast as C bindings For parsing binary protocols
/ database drivers
felixge The Story
felixge early 2010
felixge No MySQL module for node.js early 2010
felixge
felixge Pure JS / No C/C++
felixge Before Buffers became usable
felixge The Parser was using JavaScript Strings
felixge Node.js Trivia
felixge “ Buffers” used to be called “Blobs”
felixge For 3 min and 15 sec
felixge RIP Blobs ✞
felixge Sun Dec 13 08:39:20 2009 - Sun Dec 13
08:42:45 2009
felixge Anyway
felixge mysql can be done without libmysql
felixge
felixge No good deed goes unpunished
felixge Sir Isaac Newton
felixge Third Law of Motion
“When a first body exerts a force F1 on a
second body, the second body simultaneously exerts a force F2 = −F1 on the first body. This means that F1 and F2 are equal in magnitude and opposite in direction.”
felixge Third Law of Github
“When a first person pushes a library L1 into a
remote repository, a second person simultaneously starts working on a second library L2 which will be equally awesome, but in a different way.”
felixge <3 Github!
felixge
@felixge felixge Benchmark • Parse ~180 MB / 100.000 rows
of MySQL result data • 5 Columns: id, title, text, created, updated • -> create 100k objects with 500k keys + 500k values
felixge 0 500 1,000 1,500 mysql−0.9.6 mysql−libmysqlclient−1.5.1 benchmark mbit benchmark
mysql−0.9.6 mysql−libmysqlclient−1.5.1
felixge Of course.
felixge libmysql = C
felixge my library = JavaScript
felixge C > JS, right?
felixge But V8!
felixge And Crankshaft!!
felixge Node.js !!!1!
felixge Was I living a lie?
felixge Kind of
felixge V8 / Node = Tools
felixge Performance is not a tool
felixge Performance is hard work & data analysis
felixge 0 500 1,000 1,500 mysql−0.9.6 mysql−libmysqlclient−1.5.1mysql−2.0.0−alpha3 benchmark mbit benchmark
mysql−0.9.6 mysql−libmysqlclient−1.5.1 mysql−2.0.0−alpha3
felixge Third Law of Github
felixge
felixge 0 1,000 2,000 3,000 4,000 mysql−0.9.6 mysql−libmysqlclient−1.5.1 mysql−2.0.0−alpha3 mariadb−0.1.7
benchmark mbit benchmark mysql−0.9.6 mysql−libmysqlclient−1.5.1 mysql−2.0.0−alpha3 mariadb−0.1.7
felixge Time to give up?
felixge NEVER!
felixge New Parser
@felixge felixge 0 2,000 4,000 6,000 mysql2 new−parser benchmark mbit
benchmark mysql2 new−parser
felixge Third law of Github?
felixge Endgame
felixge Last bottleneck: V8 / Creating JS Objects
felixge Also: MySQL Server saturated
felixge Anyway
felixge How to write fast JS
felixge Does not work
@felixge felixge Profiling • Good at telling you which functions
are slow • Bad at telling you how to fix it
felixge Taking performance advice from strangers
@felixge felixge Taking performance advice from strangers • Good for
ideas & inspiration • But useless when applied cargo-cult style
@felixge felixge for (var i = 0; i < array.length;
i++) { // do some work with array[i] }
@felixge felixge for (var i = 0, length = array.length;
i < length; i++) { // do some work with array[i] }
felixge What Does Work?
felixge Benchmark Driven Development
@felixge felixge Benchmark Driven Development • Similar to test driven
development • Use it when performance is an explicit design goal • Benchmark first > benchmark after !
felixge 1 function benchmark() { 2 // intentionally empty 3
}
felixge 1 while (true) { 2 var start = Date.now();
3 benchmark(); 4 var duration = Date.now() - start; 5 console.log(duration); 6 }
@felixge felixge Benchmark Driven Development • Next step: Implement a
tiny part of your function • Example: Parse headers of MySQL packets • Look at impact, tweak code, repeat
@felixge felixge Example Results • try...catch is ok • big
switch statement = bad • function calls = very cheap • buffering is ok
@felixge felixge Favorite Optimization: Loop unrolling with eval()’s good twin
new Function()
@felixge felixge 1 function parseRow(columns, parser) { 2 var row
= {}; 3 for (var i = 0; i < columns.length; i++) { 4 row[columns[i].name] = parser.readColumnValue(); 5 } 6 return row; 7 }
@felixge felixge 1 function parseRow(columns, parser) { 2 return {
3 id : parser.readColumnValue(), 4 title : parser.readColumnValue(), 5 body : parser.readColumnValue(), 6 created : parser.readColumnValue(), 7 updated : parser.readColumnValue(), 8 }; 9 }
@felixge felixge How can we unroll this loop at runtime?
@felixge felixge 1 var code = 'return {\n'; 2 3
columns.forEach(function(column) { 4 code += '"' + column.name + '":' + 'parser.readColumnValue(),\n'; 5 }); 6 7 code += '};\n'; 8 9 var parseRow = new Function('columns', 'parser', code);
PLEASE DO NOT REMEMBER THIS - DO YOUR OWN BENCHMARKS!!!
@felixge felixge Data Analysis
@felixge felixge Data analysis • Produce data points as tab
separated values • Add as many VM/OS metrics as you can get to every line • Do not mix data and analysis !!
@felixge felixge Recommended Tools • node benchmark.js | tee results.tsv
• R Programming language (with ggplot2) ! • Makefiles, Image Magick, Skitch
@felixge felixge Why?
@felixge felixge 0 2,000 4,000 6,000 mysql2 new−parser benchmark mbit
benchmark mysql2 new−parser
@felixge felixge • • • • • • • •
• • • • • • • • • • • • • • • • • • • • • •• • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • •• • • • • • • • • • • •• • • • • • • • • • • • • • •• • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • •• • • • • • • • • • • • • • • • • • • • • • • • • •• • • • • • • • • • • • • • • • • • • • •• • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • •• • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • 3,000 4,000 5,000 6,000 mysql2 new−parser benchmark mbit benchmark • • mysql2 new−parser
@felixge felixge • • • • • • • •
• • • • • • • • • • • • • • • • • • • • • •• • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • •• • • • • • • • • • • •• • • • • • • • • • • • • • •• • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • •• • • • • • • • • • • • • • • • • • • • • • • • • •• • • • • • • • • • • • • • • • • • • • •• • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • •• • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • 3,000 4,000 5,000 6,000 mysql2 new−parser benchmark mbit benchmark • • mysql2 new−parser Dafuq? Dafuq?
@felixge felixge 3,000 4,000 5,000 6,000 0 100 200 300
number mbit benchmark mysql2 new−parser
@felixge felixge 10 20 30 0 100 200 300 number
Heap Total (MB) benchmark mysql2 new−parser
@felixge felixge 5 10 15 0 100 200 300 number
Heap Used (MB) benchmark mysql2 new−parser
@felixge felixge tl;dr
@felixge felixge 1. Write a benchmark 2. Write/change a little
code 3. Collect data 4. Find problems 5. Goto 2
@felixge felixge Thank you Felix Geisendörfer
@felixge felixge github.com/felixge/faster-than-c All benchmarks, results and analysis scripts Felix
Geisendörfer