hardcore-v8



hardcore-v8

0 0


hardcore-v8

Google DevFest 2013 V8 Profiling presentation

On Github luismreis / hardcore-v8

Hardcode V8

Keeping your constants constant and your volatiles docile

Hardcore V8

Producing the finest techno at 160BPM with JS

Hardcore V8

Sorry, not making that joke.

Hardcore V8

Lets get serious!

Squeezing performance out of V8.

Who is this guy ?!

  • Long time java enthusiast
  • Dev Team Head Honcho at pmelink/yunit
  • Agile practitioner
  • Hardware enthusiast
  • ruby/rails, js/node fan
  • Recently joined ranks at SAPO

Follow me on twitter! @luismreis

Content

  • Background
  • Building V8 for fun and glory
  • Memory Profiling
  • Performance Profiling
  • Other tools

Background

  • Hey! What if he had a tweet wall on LXJS ?
  • Powered by an rPI ?
  • Running on node.js ?
  • Awesome GPU
  • Terrible CPU

Background

Building V8

  • Using node on macports ? You are already doing it.
  • Node bundles V8
  • Why ?

Building V8

  • Standard V8 build (On a regular machine)
    build/gyp_v8
    
    make release
  • Standard V8 build (On the rPI)
    build/gyp_v8
    
    make arm.release armv7=false vfp3=off hardfp=on\
         disassembler=on console=readline gdbjit=on\
         library=shared

Building Node

  • Building node
    PREFIX=$HOME/opt/node
    
    ./configure\
     --prefix=$PREFIX
    
    make install
  • Using node with your custom V8 build
    PREFIX=$HOME/opt/node
    
    ./configure\
     --shared-v8\
     --shared-v8-includes=$HOME/opt/v8/include\
     --shared-v8-libpath=$HOME/opt/v8/lib\
     --prefix=$PREFIX
    
    make install

Running V8

  • Off course, if you're running Chrome...
  • V8 bundles it's own shell: "d8". d8 sucks. big time. #bigtime
  • node can pass options to the v8 runtime.
    node --v8-options
                  
  • Eg. running the profiler.
    node --prof --noprof-lazy
                  

Memory profiling

  • Troubleshooting memory consumption
  • General Strategy
    • From time to time
    • Take a memory snapshot
    • Check whats growing
  • Chrome is fully equiped to do this.
  • On node.js use Ben Noordhuis’s heapdump module

Memory profiling

  • Taking snapshots
  • Place this code on the top of your node app:
    require('heapdump');
    fs.readdirSync('.').map(function (filename) {
      if (filename.match(/^heapdump-/)) {
        console.log(filename);
        fs.unlinkSync(filename);
      }
    });
    
    setInterval(function heapDumper() {
      process.kill(process.pid, 'SIGUSR2');
    }, 15000);
                  

Memory profiling

  • Analyzing Heap Dumps
  • Just Use Chrome Dev Tools

Memory profiling

var LIMIT = 1000000;
function Spinner() {
  var buffer = new Array(LIMIT);
  var i = 0;
  setInterval(function () {
    buffer[i] = Date.now() * (1 + Math.sqrt(5)) / 2;
    i = (i + 1) % LIMIT;
  }, 200);
}

var i = 0;
var mouseClick = function () {
  new Spinner();
  if (i++ < 100) {
    setTimeout(mouseClick, 200);
  }
}

mouseClick();
          

CPU Profiling

  • Collecting Samples
    node --prof --noprof-lazy my-script.js
                  
  • Every 1ms, log a stack trace to v8.log

CPU Profiling

Analyzing

mac-tick-processor v8.log > v8.log.processed
          

CPU Profiling

Project Euler 1st Problem

function multiplesOf3and5() {
  var result = [], sum = 0;
  for (var i = 0; i < 1000 * 1000; i++) {
    if (i % 3 === 0 || i % 5 === 0) {
      sum += i;
      result.push(i);
    }
  }
  return [result, result.length, sum];
}

for (var i = 100; i > 0; i--) {
  var res = multiplesOf3and5();
  if (i === 1) {
    print('length: ' + res[1] + ' - sum: ' + res[2]);
  }
}
          

CPU Profiling

Project Euler 1st Problem

function multiplesOf3and5() {
  var result = [], j = 0, sum = 0;
  for (var i=0; i < 1000 * 1000; i++) {
    if (i % 3 === 0 || i % 5 === 0) {
      if (j == result.length) {
        result.length += 1000;
      }
      sum += i;
      result[j++] = i;
    }
  }
  return [result, j, sum];
}

for (var i = 100; i > 0; i--) {
  var res = multiplesOf3and5();
  if (i === 1) {
    print('length: ' + res[1] + ' - sum: ' + res[2]);
  }
}
          

CPU Profiling

Project Euler 1st Problem

var result = new Array(1000), size, sum;

function multiplesOf3and5() {
  size = 0;
  for (var i = 0; i < 1000 * 1000; i++) {
    if (i % 3 === 0 || i % 5 === 0) {
      if (size === result.length) {
        result.length += 1000;
      }
      sum += i;
      result[size++] = i;
    }
  }
}

for (var i = 100; i > 0; i--) {
  multiplesOf3and5();
  if (i === 1) {
    print('length: ' + size + ' - sum: ' + sum);
  }
}
          

console.log('Thank you!');