node/benchmark
Brendan Ashworth 9da168b71f buffer: optimize Buffer.byteLength
Buffer.byteLength is important for speed because it is called whenever a
new Buffer is created from a string.

This commit optimizes Buffer.byteLength execution by:
- moving base64 length calculation into JS-land, which is now much
  faster
- remove redundant code and streamline the UTF8 length calculation

It also adds a benchmark and better tests.

PR-URL: https://github.com/nodejs/io.js/pull/1713
Reviewed-By: Trevor Norris <trev.norris@gmail.com>
Reviewed-By: Ben Noordhuis <info@bnoordhuis.nl>
2015-05-22 15:31:03 -07:00
..
arrays bench: Consistency in benchmark filenames 2013-02-19 17:16:55 -08:00
buffers buffer: optimize Buffer.byteLength 2015-05-22 15:31:03 -07:00
crypto benchmark: add rsa/aes-gcm performance test 2015-04-04 12:37:26 +09:00
events benchmark: bump eventemitter number of iterations 2015-02-07 00:54:38 +02:00
fs benchmark: Correct the bufferSize to highWaterMark 2013-11-06 16:32:22 +04:00
http benchmark: fix chunky client benchmark execution 2015-04-03 00:56:45 -04:00
misc node: improve nextTick performance 2015-05-01 21:27:34 -04:00
net benchmark: fix chunky client benchmark execution 2015-04-03 00:56:45 -04:00
querystring benchmark: add a few querystring benchmarks 2015-02-14 23:41:52 -08:00
tls benchmark: fixate ciphers in tls benchmarks 2013-12-07 02:32:03 +04:00
url lib: micro-optimize url.resolve() 2014-12-20 21:33:52 +01:00
common.js benchmark: don't check wrk in non-http benchmark 2015-04-09 12:09:09 +02:00
compare.js benchmark: allow compare via fine-grained filters 2015-02-04 16:55:18 -05:00
fs-write-stream-throughput.js fs: Change default WriteStream config, increase perf 2013-02-15 18:48:43 -08:00
http_bench.js Remove excessive copyright/license boilerplate 2015-01-12 15:30:28 -08:00
http_server_lag.js Typo in http_server_lag.js script 2012-03-06 19:31:16 -08:00
http_simple_auto.js bench: use res.end() for chunked encoding 2012-12-20 11:44:10 +01:00
http_simple_bench.sh benchmark: fix command name in benchmark scripts 2015-01-14 02:29:59 +01:00
http_simple_cluster.js bench: start a worker for each CPU 2012-05-25 00:35:10 +02:00
http_simple.js bench: Make http easier to profile 2013-02-25 17:47:28 -08:00
http_simple.rb fix whitespace errors 2010-06-29 23:59:24 -07:00
http-flamegraph.sh benchmark: fix command name in benchmark scripts 2015-01-14 02:29:59 +01:00
http.sh benchmark: fix command name in benchmark scripts 2015-01-14 02:29:59 +01:00
idle_clients.js Add extra anti-DoS tech to net.Server 2010-10-27 12:09:16 -07:00
idle_server.js Abstract out a Server.prototype.pause method 2010-10-28 11:42:22 -07:00
io.c bench: Make io.c output easier to read 2013-02-19 14:14:37 -08:00
plot_csv.R benchmark: add plot_csv R graphing script 2015-03-16 21:26:05 -07:00
plot.R benchmark: fix command name in benchmark scripts 2015-01-14 02:29:59 +01:00
README.md benchmark: check for wrk ahead of running benchmarks 2015-03-04 20:25:49 -08:00
report-startup-memory.js Add startup memory script to benchmarks 2011-02-18 14:01:04 -08:00
static_http_server.js benchmark: Add resume() in static_http_server 2013-01-17 14:54:59 -08:00

io.js core benchmark tests

This folder contains benchmark tests to measure the performance for certain io.js APIs.

Prerequisites

Most of the http benchmarks require wrk and ab being installed. These are most often available through your preferred package manager.

How to run tests

There are two ways to run benchmark tests:

  1. Run all tests of a given type, for example, buffers
iojs benchmark/common.js buffers

The above command will find all scripts under buffers directory and require each of them as a module. When a test script is required, it creates an instance of Benchmark (a class defined in common.js). In the next tick, the Benchmark constructor iterates through the configuration object property values and run the test function with each of the combined arguments in spawned processes. For example, buffers/buffer-read.js has the following configuration:

var bench = common.createBenchmark(main, {
    noAssert: [false, true],
    buffer: ['fast', 'slow'],
    type: ['UInt8', 'UInt16LE', 'UInt16BE',
        'UInt32LE', 'UInt32BE',
        'Int8', 'Int16LE', 'Int16BE',
        'Int32LE', 'Int32BE',
        'FloatLE', 'FloatBE',
        'DoubleLE', 'DoubleBE'],
        millions: [1]
});

The runner takes one item from each of the property array value to build a list of arguments to run the main function. The main function will receive the conf object as follows:

  • first run:
    {   noAssert: false,
        buffer: 'fast',
        type: 'UInt8',
        millions: 1
    }
  • second run:
    {
        noAssert: false,
        buffer: 'fast',
        type: 'UInt16LE',
        millions: 1
    }

...

In this case, the main function will run 2214*1 = 56 times. The console output looks like the following:

buffers//buffer-read.js
buffers/buffer-read.js noAssert=false buffer=fast type=UInt8 millions=1: 271.83
buffers/buffer-read.js noAssert=false buffer=fast type=UInt16LE millions=1: 239.43
buffers/buffer-read.js noAssert=false buffer=fast type=UInt16BE millions=1: 244.57
...
  1. Run an individual test, for example, buffer-slice.js
iojs benchmark/buffers/buffer-read.js

The output:

buffers/buffer-read.js noAssert=false buffer=fast type=UInt8 millions=1: 246.79
buffers/buffer-read.js noAssert=false buffer=fast type=UInt16LE millions=1: 240.11
buffers/buffer-read.js noAssert=false buffer=fast type=UInt16BE millions=1: 245.91
...
  1. Run tests with options

This example will run only the first type of url test, with one iteration. (Note: benchmarks require many iterations to be statistically accurate.)

iojs benchmark/url/url-parse.js type=one n=1

Output:

url/url-parse.js type=one n=1: 1663.74402

How to write a benchmark test

The benchmark tests are grouped by types. Each type corresponds to a subdirectory, such as arrays, buffers, or fs.

Let's add a benchmark test for Buffer.slice function. We first create a file buffers/buffer-slice.js.

The code snippet

var common = require('../common.js'); // Load the test runner

var SlowBuffer = require('buffer').SlowBuffer;

// Create a benchmark test for function `main` and the configuration variants
var bench = common.createBenchmark(main, {
  type: ['fast', 'slow'], // Two types of buffer
  n: [512] // Number of times (each unit is 1024) to call the slice API
});

function main(conf) {
  // Read the parameters from the configuration
  var n = +conf.n;
  var b = conf.type === 'fast' ? buf : slowBuf;
  bench.start(); // Start benchmarking
  for (var i = 0; i < n * 1024; i++) {
    // Add your test here
    b.slice(10, 256);
  }
  bench.end(n); // End benchmarking
}