A benchmarking library. As used on jsPerf.com.

Overview

Benchmark.js v2.1.4

A robust benchmarking library that supports high-resolution timers & returns statistically significant results. As seen on jsPerf.

Documentation

Download

Installation

Benchmark.js’ only hard dependency is lodash. Include platform.js to populate Benchmark.platform.

In a browser:

<script src="lodash.js"></script>
<script src="platform.js"></script>
<script src="benchmark.js"></script>

In an AMD loader:

require({
  'paths': {
    'benchmark': 'path/to/benchmark',
    'lodash': 'path/to/lodash',
    'platform': 'path/to/platform'
  }
},
['benchmark'], function(Benchmark) {/*…*/});

Using npm:

$ npm i --save benchmark

In Node.js:

var Benchmark = require('benchmark');

Optionally, use the microtime module by Wade Simmons:

npm i --save microtime

Usage example:

var suite = new Benchmark.Suite;

// add tests
suite.add('RegExp#test', function() {
  /o/.test('Hello World!');
})
.add('String#indexOf', function() {
  'Hello World!'.indexOf('o') > -1;
})
// add listeners
.on('cycle', function(event) {
  console.log(String(event.target));
})
.on('complete', function() {
  console.log('Fastest is ' + this.filter('fastest').map('name'));
})
// run async
.run({ 'async': true });

// logs:
// => RegExp#test x 4,161,532 +-0.99% (59 cycles)
// => String#indexOf x 6,139,623 +-1.00% (131 cycles)
// => Fastest is String#indexOf

Support

Tested in Chrome 54-55, Firefox 49-50, IE 11, Edge 14, Safari 9-10, Node.js 6-7, & PhantomJS 2.1.1.

BestieJS

Benchmark.js is part of the BestieJS “Best in Class” module collection. This means we promote solid browser/environment support, ES5+ precedents, unit testing, & plenty of documentation.

Comments
  • Strange results

    Strange results

    Why is benchmark.js not getting accurate performance data? I rewrote the test to use the Date object and it's able to determine which method is faster.

    invalid 
    opened by bootstraponline 16
  • Async with callbacks and without needing to set

    Async with callbacks and without needing to set "defer" option

    Currently to make a benchmark async, you need to set an option defer to true.

    Instead of flag approach, why don't we just check if the the function passed to benchmark and saved internally as bench.fn has an argument that is called directly (simple callback) or has a promise method #resolve() that is called when the test is finished?

    The following function can detect an async function for the purposes of benchmark.js

    // Solution based on this hack to extract function parameters:
    // http://stackoverflow.com/questions/1007981/how-to-get-function-parameter-names-values-dynamically-from-javascript
    var STRIP_COMMENTS = /((\/\/.*$)|(\/\*[\s\S]*?\*\/))/mg;
    function isAsyncFunction(fn) {
      var async = false;
      if (typeof fn === 'function' && fn.length > 0) {
        var fnStr = fn.toString().replace(STRIP_COMMENTS, '');
        var params = fnStr.slice(fnStr.indexOf('(')+1, fnStr.indexOf(')')).match(/([^\s,]+)/g);
    
        // Should we check if any params are functions or only the last param
        // since that is convention. Or will async benchmarks only ever have
        // exactly one argument, either a callback or a deferred. 
        async = params.some(function(token){
          var withoutParam = fnStr.slice(fnStr.indexOf(token)).slice(token.length);
          var atFirstUsage = withoutParam.slice(withoutParam.indexOf(token));
          var charAfterTokenUsage = atFirstUsage.charAt(token.length);
    
          if (charAfterTokenUsage === '(') {
            // Should we also check if the function is executed with either 
            // #call() or #apply()? Will a test callback ever be called with
            // either?
            return true;
          }
          if (charAfterTokenUsage === '.' && atFirstUsage.indexOf('resolve()') === token.length + 1) {
            // Should we also check for other methods on the deferred object
            // such as:
            return true;
          }
        });
      }
      return async;
    }
    

    This function could be modified to return a string or null instead of a boolean, where the string would be either "promise" or "callback" when the test is async. If you know the user expects a deferred, you can pass the test a deferred. And if the user expects a callback, you can pass the test a callback.

    I'm still figuring out the best place to call this function to determine whether or not a test is async, and I'm also trying to figure out how to make it accept a callback.

    enhancement won't fix 
    opened by andrewdeandrade 12
  • "Unrecognized token [" created in the preprocess function

    Benchmark.js on Chromium is buggy because of the UID interpolation in the preprocess method.

    RegExp.exec returns an array, so /\d+/.exec("uid123") returns ["123"].

    When used with the String.replace function, it usually works fine, however on Chromium ("var r$ = 3").replace(/\$/g, ["123"]) results in "var r[123] = 3" which cannot be compiled and causes Benchmark.js to fail.

    won't fix 
    opened by levjj 10
  • Add a benchmark `assert` option to pre-run and test that it returns an expected result.

    Add a benchmark `assert` option to pre-run and test that it returns an expected result.

    Add a Benchmark assert option to pre-run and test that it returns an expected result. This can be useful to ensure snippets being tested at least return the same result.

    enhancement won't fix 
    opened by jdalton 10
  • Passing variables to the setUp method

    Passing variables to the setUp method

    Firstly, thnx for all the effort you've guys put into benchmark.js - much appreciated.

    I'm opening this issue more like a request for comments / question rather than a very precise bug report. My use case is the following one: I'm using benchmark.js with the code that is written using the CommonJS and the code under test needs to be require-ed in the setUp method. But since benchmark.js is "compiling" / "stringifing" benchmark methods I can use the closure scope to get my hand on the require method (or maybe I simply don't know how to do it properly...).

    What I'm doing as of today is a work-arround that consists of passing a non-standard option to the benchmark like so:

    {
        setup: setUp,
        teardown: function () {
            document.body.removeChild(outDiv);
        },
        require: require
    }
    

    and then, in the setUp method I'm doing: var require = this.benchmark._original.options.require;. This way I can access the require variable in both the setup and test method.

    While the above works I'm kind of not happy with it and suspect that other people might have a similar use-case of passing a variable defined in the closure scope to benchmark methods. Given the above my questions are the following one:

    • is there a better / canonical method of tackling this use-case?
    • if not, do you think there is something we could do on the benchmark.js side to support this and similar use-cases?

    Would be grateful for any input.

    enhancement 
    opened by pkozlowski-opensource 9
  • Add asynchronous support to setup and teardown.

    Add asynchronous support to setup and teardown.

    Hello,

    I was trying benchmark performance between indexedDB#add and indexedDB#put with the same data sets, but according to this closed issue it is not possible to properly setup with asynchronous function calls in benchmark.js.

    IndexedDB is asynchronous only. Opening, creating, CRUD, etc. are all done async in the browser.

    Ideally my benchmark would look something like this pseudocode:

    setup = function () {
      // open database connection/create db
      // create store
      // populate benchmark data
    }
    
    teardown = function () {
      // delete database
      // close db connection
    }
    
    test1 = function add () {
      // get transaction request
      // while (data) request.add
    }
    
    test1 = function put () {
      // get transaction request
      // while (data) request.put
    }
    

    I propose adding support for asynchronous for setup and teardown as more and more modern browser apis are async only.

    enhancement 
    opened by octatone 9
  • Event.target not set correctly

    Event.target not set correctly

    Benchmark looks great.

    Unfortunately, the example on the home page doesn't seem to work out of the box on node v0.8.

    I tried making a new file and running it in node

    var Benchmark = require('./benchmark.js');
    
    var suite = new Benchmark.Suite;
    
    // add tests
    suite.add('RegExp#test', function() {
      /o/.test('Hello World!');
    })
    .add('String#indexOf', function() {
      'Hello World!'.indexOf('o') > -1;
    })
    .add('String#match', function() {
      !!'Hello World!'.match(/o/);
    })
    // add listeners
    .on('cycle', function(event) {
      console.log(String(event.target));
    })
    .on('complete', function() {
      console.log('Fastest is ' + this.filter('fastest').pluck('name'));
    })
    // run async
    .run({ 'async': true });
    

    which will output this:

    undefined
    undefined
    undefined
    Fastest is String#indexOf
    

    It looks like the process is working correctly, but the Event objects are not being formed correctly. The cycle event is missing the target property and looks like this:

    { type: 'cycle' }
    

    I can see in the source that event.type is set explicitly (e.g., line 1659 for the cycle event) while event.target is coming from elsewhere (last, bench). Nothing jumps out to me about any of this though, so I was hoping someone else might see something.

    Also, I'm running on the brand new node v0.8 (released yesterday), in case that could be related.

    invalid 
    opened by kevinrobinson 9
  • Exception thrown from internals of Benchmark on simple example...

    Exception thrown from internals of Benchmark on simple example...

    I tried this simple example (node v7):

    var Benchmark = require("benchmark");
    
    Benchmark.options.onStart = function onStart(evt){
    	console.log("onStart",evt.target.name);
    };
    
    var main = Benchmark.Suite("main");
    
    main.add("test",function(){
    	var x = new Array(1400);
    });
    
    main.run();
    

    When I run this on the command line, the output I get is:

    bug

    1. I'm not sure why onStart is getting called twice?
    2. I don't understand why my usage is causing this exception?

    Am I missing something?

    bug 
    opened by getify 8
  • Webpack support

    Webpack support

    Webpack emits the following warning when we import benchmark.js

    import Benchmark from 'benchmark'
    
    WARNING in ./~/benchmark/benchmark.js
    Critical dependency: the request of a dependency is an expression
    

    Moreover, when i'm running the test suite given in this example, i get plenty of those errors even though the test completes with success. :

    Uncaught ReferenceError: define is not defined
    

    So i can't simply import this module in my project to compare the performances of two functions. Do I have to create a separate application and to define lodash in global scope, in order to compare 2 functions which are in my project ?

    This would be annoying...

    enhancement won't fix 
    opened by rgranger 7
  • Question: untimed setup portion

    Question: untimed setup portion

    I have a quick question regarding benchmark.js.I'm currently building some benchmarks that require some set up before the benchmark itself can be executed and I would like this set up to be placed outside of the timed portion of the code. Is there a utility or option that benchmark.js provides to do this?

    I tired onCycle,setup and onStart but none of these seem to execute just before the benchmark itself every time, which is the behavior that I need.

    question 
    opened by Poincare 7
  • How to make it go faster?

    How to make it go faster?

    I'm writing a library that needs to be very efficient.

    I am often making changes where I need do a benchmark every change.

    Benchmark js takes around 85 samples for each item in the suite and ends up taking 30 seconds total.

    Even though it would be less accurate, I'm looking for a way of making it much quicker during development. Ideally between 1 and 5 seconds.

    I looked through the options and couldn't find one to make it complete faster, even though I tried all the ones that looked promising. Regardless, it takes around 85 samples.

    Is there any way to do this?

    question 
    opened by githubaccount624 7
  • Too many significant digits being reported

    Too many significant digits being reported

    The Benchmark results typically reported by these runs report a mean number of ops/sec with too many significant digits. Reporting the confidence interval is great, but all the digits reported make it hard to compare results.

    I'm trying to remember the math behind this, but if the confidence interval is +/- 1%, it seems there should be no more than 3 significant digits reported, isn't that right?

    This can be done fairly easily using the number's toPrecision( digits ) method. The returned value is a string and can be in scientific notation. Under normal circumstances, it shouldn't need commas.

    opened by BurtHarris 0
  • How do I get the same test results every time?

    How do I get the same test results every time?

    Every test run I get different results on a simple code (for example, a simple for loop)

    What settings do I need to specify in order to get stable results for tests and understand that the tests are correct and not a random error?

    opened by budarin 1
  • What is the

    What is the "x runs sampled" in the output results?

    At first, I thought it was the number of executions of suite, but it was not.

    I didn't find the detailed concept of sample on the Internet, benchmark The js source code is not understood.

    The approximate guess is:

    1. The sample means how many samples have been executed.
    2. Each sample contains N executions of suite.
    3. Each sample has a fixed execution time

    I don't know if the above conjecture is correct. Please give me some advice. Thank you!

    opened by aweiu 0
  • TypeError: Cannot read properties of undefined (reading 'parentNode')

    TypeError: Cannot read properties of undefined (reading 'parentNode')

    I'm trying to use the library:

    var Benchmark = require('benchmark');
    
    var str = 'A'.repeat(10000);
    
    var suite = new Benchmark.Suite();
    
    suite.add('partition', function() {
        //$.terminal.partition(str);
    }).add('split_equal', function() {
        //$.terminal.split_equal(str, 100);
    }).run({ 'async': false });
    
    

    And got this error in NodeJS 18.

    this is the stack trace:

    /home/kuba/projects/jcubic/terminal/repo/node_modules/benchmark/benchmark.js:664
              parent = sibling.parentNode,
                               ^
    
    TypeError: Cannot read properties of undefined (reading 'parentNode')
        at runScript (/home/kuba/projects/jcubic/terminal/repo/node_modules/benchmark/benchmark.js:664:28)
        at createFunction (/home/kuba/projects/jcubic/terminal/repo/node_modules/benchmark/benchmark.js:517:9)
        at createFunction (/home/kuba/projects/jcubic/terminal/repo/node_modules/benchmark/benchmark.js:524:44)
        at createCompiled (/home/kuba/projects/jcubic/terminal/repo/node_modules/benchmark/benchmark.js:1714:23)
        at clock (/home/kuba/projects/jcubic/terminal/repo/node_modules/benchmark/benchmark.js:1608:58)
        at clock (/home/kuba/projects/jcubic/terminal/repo/node_modules/benchmark/benchmark.js:1818:20)
        at cycle (/home/kuba/projects/jcubic/terminal/repo/node_modules/benchmark/benchmark.js:2007:49)
        at Benchmark.run (/home/kuba/projects/jcubic/terminal/repo/node_modules/benchmark/benchmark.js:2114:13)
        at execute (/home/kuba/projects/jcubic/terminal/repo/node_modules/benchmark/benchmark.js:860:74)
        at invoke (/home/kuba/projects/jcubic/terminal/repo/node_modules/benchmark/benchmark.js:970:20)
    

    I'm testing a library that uses JSDom to work properly in Node.

    opened by jcubic 0
  • Consider using symbols for tracing data

    Consider using symbols for tracing data

    This week I was writing a benchmark for some of our tracing code which I'm trying to refactor and speed up.

    I stared at this error for far too long:

    /Users/jason.marshall/Projects/foo/node_modules/benchmark/benchmark.js:1901
                size = sample.push(clone.times.period),
                              ^
    
    TypeError: Cannot read property 'push' of undefined
        at Array.evaluate (/Users/jason.marshall/Projects/foo/node_modules/benchmark/benchmark.js:1901:27)
    

    After a night's sleep it dawned on me that I might be clobbering internal state:

                event.target.stats = new ...;
    

    The fact that the error doesn't talk about 'stats' kept me from connecting the dots.

    If Benchmark is assuming ES6, which I believe it does, it might make sense for the bookkeeping data to be stored under symbols instead of as regular property names. That decreases the likelihood of someone accidentally changing internal state on the object.

    Alternatively, are there other ways to do setup for a benchmark? The offending code above I believe was based off of following examples in the docs. If there's a safer way to write an onStart I'd be happy to file a PR to fix the docs.

    opened by jdmarshall 0
  • Document how to run benchmark.js

    Document how to run benchmark.js

    The Benchmark.js home page shows how to write a test suite, but at no point does it show how to run the test suite and get results.

    There is no bin, as you would get with testing frameworks, so my best guess at the correct answer was:

    lib/settings/index.bench.js
    

    But this only results in a few lines of console code from the code under test and then nothing. No statistics, no output files.

    Stepping through in a debugger, the code is definitely running. It's just not accomplishing anything.

    opened by jdmarshall 1
Owner
BestieJS Modules
BestieJS Modules
This library was designed to be used in SPA framework wrappers for the FingerprintJS Pro Javascript Agent

Framework-agnostic SPA service wrapper. Use it to build a FingerprintJS Pro wrapper for your favorite framework.

FingerprintJS 12 Sep 3, 2022
A simple implementation of a task list application that can be used to add, remove, edit and check users tasks

"To-do list" is a tool that helps to organize daily activites. It simply lists the things which are needed to be done and allows user to mark them as complete. In this step of project, the CRUD (create, update, delete) methods are implemented. This simple web page is built using webpack and served by a webpack dev server.

Zahra Arshia 5 Mar 28, 2022
A platform detection library.

Platform.js v1.3.6 A platform detection library that works on nearly all JavaScript platforms. Disclaimer Platform.js is for informational purposes on

BestieJS Modules 3.1k Dec 31, 2022
The perfect library for adding search, sort, filters and flexibility to tables, lists and various HTML elements. Built to be invisible and work on existing HTML.

List.js Perfect library for adding search, sort, filters and flexibility to tables, lists and various HTML elements. Built to be invisible and work on

Jonny Strömberg 10.9k Jan 1, 2023
A high-performance, dependency-free library for animated filtering, sorting, insertion, removal and more

MixItUp 3 MixItUp is a high-performance, dependency-free library for animated DOM manipulation, giving you the power to filter, sort, add and remove D

Patrick Kunka 4.5k Dec 24, 2022
Drag and drop library for two-dimensional, resizable and responsive lists

GridList Drag and drop library for a two-dimensional resizable and responsive list of items Demo: http://hootsuite.github.io/grid/ The GridList librar

Hootsuite 3.6k Dec 14, 2022
JavaScript Survey and Form Library

SurveyJS is a JavaScript Survey and Form Library. SurveyJS is a modern way to add surveys and forms to your website. It has versions for Angular, jQue

SurveyJS 3.5k Jan 1, 2023
Extensive math expression evaluator library for JavaScript and Node.js

?? Homepage Fcaljs is an extensive math expression evaluator library for JavaScript and Node.js. Using fcal, you can perform basic arithmetic, percent

Santhosh Kumar 93 Dec 19, 2022
Browser fingerprinting library with the highest accuracy and stability.

FingerprintJS is a browser fingerprinting library that queries browser attributes and computes a hashed visitor identifier from them. Unlike cookies a

FingerprintJS 18.1k Dec 31, 2022
autoNumeric is a standalone library that provides live as-you-type formatting for international numbers and currencies.

What is autoNumeric? autoNumeric is a standalone Javascript library that provides live as-you-type formatting for international numbers and currencies

AutoNumeric 1.7k Dec 16, 2022
A wrapper library for Jitsi Meet that adds audio spatialization, to be able to create virtual meeting rooms.

A wrapper library for Jitsi Meet that adds audio spatialization, to be able to create virtual meeting rooms.

Sean T. McBeth 1.1k Dec 27, 2022
Solid.js library adding signaling to built-in non-primitives

This package provides signaled versions of Javascript's built-in objects. Thanks to it, all theirs properties will be automatically tracked while using standard API.

Maciej Kwaśniak 40 Dec 29, 2022
ChelseaJS - a Javascript library for creative, generative Coding

ChelseaJS is a Javascript library for creative, generative Coding. It's simple and intuitive syntax makes it easy for everyone (including non-coders)

Prakrisht Dahiya 26 Oct 6, 2022
Estrela - a JavaScript library for building reactive web components inspired by lit

Estrela ⭐ Full Reactive Web Components Estrela is a JavaScript library for building reactive web components inspired by lit. Just like Lit, Estrela is

null 50 Oct 31, 2022
🔎 A simple, tiny and lightweight benchmarking library!

tinybench Benchmark your code easily with Tinybench, a simple, tiny and light-weight 7KB (2KB minified and gzipped) benchmarking library! You can run

Tinylibs 516 Jan 9, 2023
A caffeine driven, simplistic approach to benchmarking.

Matcha A caffeine driven, simple approach to benchmarking. Matcha allow you to design experiments that will measure the performance of your code. It i

Jake Luer 557 Nov 30, 2022
Cross-runtime benchmarking lib and cli

mitata cross-runtime benchmarking lib Install bun add mitata npm install mitata Examples import { run, bench, group, baseline } from 'mitata'; // den

evan 165 Jan 3, 2023
A frida script that can be used to find the public RSA key used in the native libakamaibmp.so shared library, seen in version 3.3.0 of Akamai BMP

Akamai BMP - RSA/AES Frida Hook This Frida script can be used to find the public RSA key used in the encryption process in Akamai BMP 3.3.0. Since ver

yog 31 Jan 8, 2023
Challenge [Frontend Mentor] - In this challenge, JavaScript was used to filter jobs based on the selected categories. Technologies used: HTML5, CSS3 and React.

Getting Started with Create React App This project was bootstrapped with Create React App. Available Scripts In the project directory, you can run: np

Rui Neto 11 Apr 13, 2022