Skip to content

Instantly share code, notes, and snippets.

@vhf
Last active November 1, 2015 11:58
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 vhf/58769c1d0462094a66a3 to your computer and use it in GitHub Desktop.
Save vhf/58769c1d0462094a66a3 to your computer and use it in GitHub Desktop.
'use strict';
var Benchmark = require('benchmark');
var suite = new Benchmark.Suite();
// #1 "naive"
function factorial1(x) {
if (x <= 0) {
return 1;
} else {
return x * factorial1(x - 1);
}
}
// #2 tail rec using a default parameter and leaking arguments
function factorial2(n) {
return facRec2(n);
}
function facRec2(_x2) {
var _arguments = arguments;
var _again = true;
_function: while (_again) {
var x = _x2;
_again = false;
var acc = _arguments.length <= 1 || _arguments[1] === undefined ? 1 : _arguments[1];
if (x <= 1) {
return acc;
} else {
_arguments = [_x2 = x - 1, x * acc];
_again = true;
acc = undefined;
continue _function;
}
}
}
// #2 tail rec using a default parameter and no leaking arguments
function factorial2b(n) {
return facRec2b(n);
}
function facRec2b(_x5) {
var $_len = arguments.length;var _arguments = new Array($_len); for(var $_i = 0; $_i < $_len; ++$_i) {_arguments[$_i] = arguments[$_i];}
var _again = true;
_functionb: while (_again) {
var x = _x5;
_again = false;
var acc = _arguments.length <= 1 || _arguments[1] === undefined ? 1 : _arguments[1];
if (x <= 1) {
return acc;
} else {
_arguments = [_x5 = x - 1, x * acc];
_again = true;
acc = undefined;
continue _functionb;
}
}
}
// #3 tail rec
function factorial3(n) {
return facRec3(n, 1);
}
function facRec3(_x3, _x4) {
var _again2 = true;
_function2: while (_again2) {
var x = _x3,
acc = _x4;
_again2 = false;
if (x <= 1) {
return acc;
} else {
_x3 = x - 1;
_x4 = x * acc;
_again2 = true;
continue _function2;
}
}
}
// suite.add('#1 no tail call', function() {
// factorial1(100);
// })
// .add('#2 TCO/default params leaking arguments', function() {
// factorial2(100);
// })
// .add('#2 TCO/default params no leaking arguments', function() {
// factorial2b(100);
// })
// .add('#3 TCO/no default params', function() {
// factorial3(100);
// })
// .on('cycle', function(event) {
// console.log(String(event.target));
// })
// .on('complete', function() {
// console.log('Fastest is ' + this.filter('fastest').pluck('name'));
// })
// .run({ 'async': true });
function printStatus(fn) {
switch(%GetOptimizationStatus(fn)) {
case 1: console.log(fn.name + ' is optimized'); break;
case 2: console.log(fn.name + ' is not optimized'); break;
case 3: console.log(fn.name + ' is always optimized'); break;
case 4: console.log(fn.name + ' is never optimized'); break;
case 6: console.log(fn.name + ' is maybe deoptimized'); break;
}
}
factorial1(100);
factorial1(100);
%OptimizeFunctionOnNextCall(factorial1);
factorial1(100);
printStatus(factorial1);
facRec2(100, 1);
facRec2(100, 1);
%OptimizeFunctionOnNextCall(facRec2);
facRec2(100, 1);
printStatus(facRec2);
facRec2b(100, 1);
facRec2b(100, 1);
%OptimizeFunctionOnNextCall(facRec2b);
facRec2b(100, 1);
printStatus(facRec2b);
facRec3(100, 1);
facRec3(100, 1);
%OptimizeFunctionOnNextCall(facRec3);
facRec3(100, 1);
printStatus(facRec3);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment