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
780
Programming flying robots with JavaScript
felixge
2
960
Programming flying robots with JavaScript
felixge
0
600
Programming an AR Drone Firmware with JS (de)
felixge
1
620
Flying robots over a 10.000 mile distance with JavaScript.
felixge
0
490
Faster than C?
felixge
1
640
The power of node.js (with quadcopters)
felixge
0
500
Faster than C?
felixge
0
420
Faster than C? Parsing binary data in JavaScript.
felixge
3
3.8k
Other Decks in Programming
See All in Programming
可変性を制する設計: 構造と振る舞いから考える概念モデリングとその実装
a_suenami
10
1.5k
中級グラフィックス入門~効率的なメッシュレット描画~
projectasura
4
2.4k
DynamoDBは怖くない!〜テーブル設計の勘所とテスト戦略〜
hyamazaki
0
180
Terraform やるなら公式スタイルガイドを読もう 〜重要項目 10選〜
hiyanger
11
2.8k
知って得する@cloudflare_vite-pluginのあれこれ
chimame
1
140
DataformでPythonする / dataform-de-python
snhryt
0
150
Comparing decimals in Swift Testing
417_72ki
0
160
Amazon Q CLI開発で学んだAIコーディングツールの使い方
licux
3
170
ZeroETLで始めるDynamoDBとS3の連携
afooooil
0
150
Quality Gates in the Age of Agentic Coding
helmedeiros
PRO
1
120
Vibe Codingの幻想を超えて-生成AIを現場で使えるようにするまでの泥臭い話.ai
fumiyakume
21
10k
Reactの歴史を振り返る
tutinoko
1
170
Featured
See All Featured
Visualizing Your Data: Incorporating Mongo into Loggly Infrastructure
mongodb
47
9.6k
Stop Working from a Prison Cell
hatefulcrawdad
271
21k
Being A Developer After 40
akosma
90
590k
Chrome DevTools: State of the Union 2024 - Debugging React & Beyond
addyosmani
7
790
個人開発の失敗を避けるイケてる考え方 / tips for indie hackers
panda_program
110
19k
Save Time (by Creating Custom Rails Generators)
garrettdimon
PRO
31
1.3k
The MySQL Ecosystem @ GitHub 2015
samlambert
251
13k
Adopting Sorbet at Scale
ufuk
77
9.5k
Six Lessons from altMBA
skipperchong
28
3.9k
Why You Should Never Use an ORM
jnunemaker
PRO
58
9.5k
Building Flexible Design Systems
yeseniaperezcruz
328
39k
[Rails World 2023 - Day 1 Closing Keynote] - The Magic of Rails
eileencodes
35
2.5k
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