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 10, 2012
Programming
1
580
Faster than C?
Presentation given at nodeconf.it.
Felix Geisendörfer
November 10, 2012
Tweet
Share
More Decks by Felix Geisendörfer
See All by Felix Geisendörfer
tus.io - Resumable File Uploads (Lightning Talk)
felixge
2
730
Programming flying robots with JavaScript
felixge
2
910
Programming flying robots with JavaScript
felixge
0
550
Programming an AR Drone Firmware with JS (de)
felixge
1
580
Faster than C?
felixge
1
1.2k
Flying robots over a 10.000 mile distance with JavaScript.
felixge
0
450
The power of node.js (with quadcopters)
felixge
0
460
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
各クラウドサービスにおける.NETの対応と見解
ymd65536
0
110
クリエイティブコーディングとRuby学習 / Creative Coding and Learning Ruby
chobishiba
0
3.9k
Keeping it Ruby: Why Your Product Needs a Ruby SDK - RubyWorld 2024
envek
0
190
フロントエンドのディレクトリ構成どうしてる? Feature-Sliced Design 導入体験談
osakatechlab
8
4.1k
CQRS+ES の力を使って効果を感じる / Feel the effects of using the power of CQRS+ES
seike460
PRO
0
140
採用事例の少ないSvelteを選んだ理由と それを正解にするためにやっていること
oekazuma
2
1k
SymfonyCon Vienna 2025: Twig, still relevant in 2025?
fabpot
3
1.2k
開発者とQAの越境で自動テストが増える開発プロセスを実現する
92thunder
1
190
テストコード文化を0から作り、変化し続けた組織
kazatohiei
2
1.5k
責務を分離するための例外設計 - PHPカンファレンス 2024
kajitack
6
1.5k
快速入門可觀測性
blueswen
0
380
Итераторы в Go 1.23: зачем они нужны, как использовать, и насколько они быстрые?
lamodatech
0
850
Featured
See All Featured
Done Done
chrislema
181
16k
Into the Great Unknown - MozCon
thekraken
33
1.5k
Responsive Adventures: Dirty Tricks From The Dark Corners of Front-End
smashingmag
251
21k
Templates, Plugins, & Blocks: Oh My! Creating the theme that thinks of everything
marktimemedia
28
2.1k
Save Time (by Creating Custom Rails Generators)
garrettdimon
PRO
28
900
Faster Mobile Websites
deanohume
305
30k
Refactoring Trust on Your Teams (GOTO; Chicago 2020)
rmw
32
2.7k
The World Runs on Bad Software
bkeepers
PRO
65
11k
Exploring the Power of Turbo Streams & Action Cable | RailsConf2023
kevinliebholz
28
4.4k
Helping Users Find Their Own Way: Creating Modern Search Experiences
danielanewman
29
2.3k
A better future with KSS
kneath
238
17k
Build The Right Thing And Hit Your Dates
maggiecrowley
33
2.4k
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 JavaScript vs C-Addons (for parsing binary protocols)
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 for spotting small functions with
stupid algorithms performing many iterations • Bad for complex functions with many primitive operations
felixge Taking performance advice from strangers
@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 felixge Taking performance advice from strangers • Good for
ideas & inspiration • But useless when applied cargo-cult style
felixge 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
@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 Make it faster!
@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);
@felixge felixge ->
@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 eval = awesome
@felixge felixge eval = awesome
@felixge felixge new Function = awesome
@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