Skip to main content
Module

x/simplestatistic/benchmarks/index.js

simple statistics for node & browser javascript
File
/* eslint no-console: 0, global-require: 0 */'use strict';var Benchmark = require('benchmark');var markdownTable = require('markdown-table');global.ss = require('simple-statistics');global.ssMaster = require('../');global.science = require('science');global.jStat = require('jstat').jStat;global.mathjs = require('mathjs');global.d3 = require('d3-array');
// We have a very simple way to benchmark single-array-input// methods, but jStat is a little more complicated - you specify// if you want _sample_ variance by adding a boolean argument to the// method. So I add it here.global.jStat.sampleVariance = function(input) { return global.jStat.variance(input, true);};
function setupInput() { var i; var input10 = []; for (i = 0; i < 10; i++) { input10.push(Math.random()); } var input100 = []; for (i = 0; i < 100; i++) { input100.push(Math.random()); } var input1000 = []; for (i = 0; i < 1000; i++) { input1000.push(Math.random()); }
var input10a = []; for (i = 0; i < 10; i++) { input10a.push(Math.random()); } var input100a = []; for (i = 0; i < 100; i++) { input100a.push(Math.random()); } var input1000a = []; for (i = 0; i < 1000; i++) { input1000a.push(Math.random()); }}
// This is the start of what will eventually be a markdown table// included in the readme.var results = [[ '', 'ss', 'science', 'jStat', 'mathjs', 'd3', 'ssMaster']];
// This is a generic 'suite maker' method that we use to test different// libraries doing the same work - it gets a name as a first argument, like// 'median', and the second argument is an array of strings that are the names// of the implementations of that function in different libraries.function suiteForMethods(name, methods, type) {
var suite = new Benchmark.Suite({ name: name, onError: function(error) { console.log(error); } });
methods.forEach(function (method) { if (type === 'two-arrays') { suite.add(method, { setup: setupInput, fn: method + '(input10, input10a);' + method + '(input100, input100a);' + method + '(input1000, input1000a);' }); } else { suite.add(method, { setup: setupInput, fn: method + '(input10);' + method + '(input100);' + method + '(input1000);' }); } });
suite .on('cycle', function(event) { console.error(String(event.target)); }) .on('complete', function() { var row = [name]; for (var i = 1; i < results[0].length; i++) { row[i] = ''; } var fastest = this.filter('fastest')[0]; this.forEach(function (event) { // This gross code figures out which column to put // each result in, because we don't have implementations // of every method in every library. var idx = results[0].indexOf(event.name.split('.')[1]); row[idx] = Math.round(event.hz).toLocaleString(); if (event === fastest) { row[idx] = '**' + row[idx] + '**'; } }); results.push(row); }) .run();}
// Here we declare all of the basic operations that we'll test, and the// functions in each library that do them.var tests = [ [ 'variance', [ 'global.ss.variance', 'global.ssMaster.variance', 'global.jStat.variance' ] ], [ 'sampleVariance', [ 'global.ss.sampleVariance', 'global.ssMaster.sampleVariance', 'global.science.stats.variance', 'global.jStat.sampleVariance', 'global.d3.variance' ] ], [ 'covariance', [ 'global.ss.sampleCovariance', 'global.ssMaster.sampleCovariance', 'global.jStat.covariance' ], 'two-arrays' ], [ 'skewness', [ 'global.ss.sampleSkewness', 'global.ssMaster.sampleSkewness', 'global.jStat.skewness' ] ], [ 'geometricMean', [ 'global.ss.geometricMean', 'global.ssMaster.geometricMean', 'global.jStat.geomean' ] ], [ 'medianAbsoluteDeviation', [ 'global.ss.medianAbsoluteDeviation', 'global.ssMaster.medianAbsoluteDeviation', 'global.mathjs.mad', 'global.jStat.meddev' ] ], [ 'median', [ 'global.ss.median', 'global.ssMaster.median', 'global.mathjs.median', 'global.jStat.median', 'global.science.stats.median', 'global.d3.median' ] ], [ 'mode', [ 'global.ss.mode', 'global.ssMaster.mode', 'global.mathjs.mode', 'global.jStat.mode', 'global.science.stats.mode' ] ], [ 'mean', [ 'global.ss.mean', 'global.ssMaster.mean', 'global.mathjs.mean', 'global.jStat.mean', 'global.science.stats.mode' ] ], [ 'min', [ 'global.ss.min', 'global.ssMaster.min', 'global.mathjs.min', 'global.jStat.min', 'global.d3.min' ] ], [ 'max', [ 'global.ss.max', 'global.ssMaster.max', 'global.mathjs.max', 'global.jStat.max', 'global.d3.max' ] ], [ 'sum', [ 'global.ss.sum', 'global.ssMaster.sum', 'global.mathjs.sum', 'global.jStat.sum', 'global.d3.sum' ] ]];
tests.forEach(function (test) { suiteForMethods(test[0], test[1], test[2]);});
// Finally, console.log spits out the content of readme.mdconsole.log('# Benchmarks');console.log('\n\nThis document is generated by `npm start`. It compares simple-statistics performance against similar libraries in JavaScript.');console.log('\n\n' + markdownTable(results));console.log('\n\nFastest libraries are in bold. Numbers are in operations per second.');console.log('\n\nssMaster is simple-statistics master branch, used for testing and proofing - it is not guaranteed to be any released version.');
console.log('\n\n### Versions\n');
['simple-statistics', 'science', 'jstat', 'mathjs', 'd3-array'].forEach(function (p) { console.log('* ' + p + ': ' + require(p + '/package').version);});