Skip to content

Instantly share code, notes, and snippets.

@jhecking
Last active August 25, 2016 08:29
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jhecking/2b53141304bf062a1e152bcd671c843f to your computer and use it in GitHub Desktop.
Save jhecking/2b53141304bf062a1e152bcd671c843f to your computer and use it in GitHub Desktop.
Optimizing handling for variadic function arguments
#!/bin/bash
node benchmark.js
var Benchmark = require('benchmark')
var suite = new Benchmark.Suite()
var handlers = require('./callback-handlers')
var cb = () => {}
var err = { code: 0 }
var result = 'async result'
// add tests
handlers.forEach(function (f) {
suite.add(f.name, function () {
f(cb, err, result)
})
})
// add listeners and run async
suite
.on('cycle', function (event) {
console.log(String(event.target))
})
.on('complete', function () {
console.log('And the winner is... ' + suite.filter('fastest').map('name') + '!')
})
.run({ async: true })
function cbSliceArguments (callback, err) {
if (err && err.code !== 0) {
return callback(err)
}
var args = Array.prototype.slice.call(arguments, 2)
args.unshift(null) // set err to null
callback.apply(undefined, args)
}
function cbArrayConstructor (callback, err) {
if (err && err.code !== 0) {
return callback(err)
}
var args = Array.apply(null, arguments)
args.shift() // remove callback argument
args[0] = null // set err to null
callback.apply(undefined, args)
}
function cbIterateArguments (callback, err) {
if (err && err.code !== 0) {
return callback(err)
}
var len = arguments.length
var args = [null]
for (var i = 2; i < len; i++) {
args[i - 1] = arguments[i]
}
callback.apply(undefined, args)
}
function cbIterateArgumentsUsingPush (callback, err) {
if (err && err.code !== 0) {
return callback(err)
}
var len = arguments.length
var args = [null]
for (var i = 2; i < len; i++) {
args.push(arguments[i])
}
callback.apply(undefined, args)
}
function cbSpreadOperator (callback, err, ...args) {
if (err && err.code !== 0) {
return callback(err)
}
callback(null, ...args)
}
function cbNaive (callback, err, arg1, arg2, arg3) {
if (err && err.code !== 0) {
return callback(err)
}
callback(null, arg1, arg2, arg3)
}
module.exports = [
cbSliceArguments,
cbArrayConstructor,
cbIterateArguments,
cbIterateArgumentsUsingPush,
cbSpreadOperator,
cbNaive
]
#!/bin/bash
if [ "$1" == "-v" ]; then
node --trace_opt --trace_deopt --allow-natives-syntax optimize.js
else
node --trace_opt --trace_deopt --allow-natives-syntax optimize.js | grep "^#"
fi
var handlers = require('./callback-handlers')
function status(f) {
switch(%GetOptimizationStatus(f)) {
case 1: return '\033[32moptimized\033[0m'
case 2: return '\033[31mnot optimized\033[0m'
case 3: return '\033[32malways optimized\033[0m'
case 4: return '\033[31mnever optimized\033[0m'
case 6: return 'maybe deoptimized'
case 7: return '\033[32moptimized by TurboFan\033[0m'
default: 'unknown'
}
}
function printStatus(f) {
console.log('# Function %s is %s', f.name, status(f))
}
var cb = function () {}
var error = { code: 0 }
var result = 'some value'
handlers.forEach((f) => {
// 2 calls are needed to go from uninitialized -> pre-monomorphic -> monomorphic
f(cb, error, result)
f(cb, error, result)
;%OptimizeFunctionOnNextCall(f)
f(cb, error, result)
printStatus(f)
})
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment