Run Node Run

Post on 13-Jan-2015

785 views 7 download

Tags:

description

A brief overview of profiling Node.js and writing code for the V8 runtime.

transcript

Run Node Run

Fine-tuning JavaScript forthe V8 Runtime

@kevinswiber kswiber@gmail.com

Agenda

• Benchmarking • V8 JavaScript Tips and Tricks• Inside Crankshaft• Profiling Node

From 365 to 5,000 requests per second.

This shit works. Swears it.

Note: This is complex, but you’ll sleep better at night.

If you can sleep at all.

This is about speed.

Speed is addictive.

Benchmarking

HTTP

$ ab -n1000 –c100 –k http://127.0.0.1/

$ siege –r100 –c100 -b http://127.0.0.1/

JMeter

ab output

Concurrency Level: 100Time taken for tests: 8.680 secondsRequests per second: 11521.27 [#/sec] (mean)Time per request: 8.680 [ms] (mean)Time per request: 0.087 [ms] (mean, across all concurrent requests)

Non-HTTP

var maxRuns = 1000;var start = Date.now();for (var i = 0; i < maxRuns; i++) { // do stuff...}var end = Date.now();

var elapsed = end – start;var timePerRun = elapsed / maxRuns;

console.log(elapsed + ‘ ms’);console.log(timePerRun + ‘ ms/run’

Faster!

Hidden Classes

function Point(x, y) { this.x = x; this.y = y;}

var p1 = new Point(1, 2);var p2 = new Point(3, 4);

Hidden Classes

function Point(x, y) { this.x = x; this.y = y;}

var p1 = new Point(1, 2);var p2 = new Point(3, 4);p2.z = 9; // ohnoes!!

Dictionary Mode

function takeOrder(row) { var order = { food: row.get(‘food’), quantity: row.get(‘qty’); }; process(order);}

Dictionary Mode

function takeOrder(row) { var order = { food: row.get(‘food’), quantity: row.get(‘qty’); }; process(order);}// ohnoes!!!for(var i = 0; i < db.length; i++) { takeOrder(db[i]);}

Try-Catch

try { // hot code} catch(e) { console.log(e);}

Try-Catch

try { process();} catch(e) { console.log(e);}

function process() { // hot code}

Hot Code

• Don’t monkey-patch.• Don’t mix types for the same property.• Avoid dictionary mode.• Set all properties in the constructor.• Move high-performance code out of try-catch.• If array.length < 65000, specify the size.

V8’s Crankshaft is Awesome

Base Compiler

Runtime Profiler

Optimizing Compiler

Deoptimization Support

JavaScript ->Hydrogen ->Lithium ->(Native)

Profiling Node

$ node --prof server.js

Note: Your benchmark will be slower.

$ lsserver.js v8.log

$ export D8_PATH=~/node/src/deps/v8$ ~/nvm/src/node-v0.8.18/deps/v8/tools/mac-tick-processor > profile.log

[JavaScript]: ticks total nonlib name 251 0.5% 0.5% LazyCompile: *Socket.write net.js:465

[C++]: ticks total nonlib name 48625 94.4% 94.4% ___psynch_rw_unlock

[GC]: ticks total nonlib name 263 0.5%

c4milo/node-webkit-agent

$ cat server.jsvar agent = require('webkit-devtools-agent');// create serverconsole.log(process.pid)

$ node server.js22341

$ kill –SIGUSR2 22341$ open http://c4milo.github.com/node-webkit-agent/21.0.1180.57/inspector.html?host=localhost:1337&page=0

More Profiling Options

--trace_opt

• Shows code optimizations.• Good for spotting hot code.

--trace_deopt

• Shows code de-optimizations.• Good for spotting type information changes in

hot code.

“If you ain’t first, you’re last!”

The plumbing should work like greased lightning.

You can’t control everything.

Fail with grace.

Benchmark regularly.

Adios!

@kevinswiber kswiber@gmail.com