{"id":15916906,"url":"https://github.com/dsfields/radargun","last_synced_at":"2025-03-24T07:31:42.719Z","repository":{"id":71797857,"uuid":"113770413","full_name":"dsfields/radargun","owner":"dsfields","description":"A benchmark utility for Node.js.","archived":false,"fork":false,"pushed_at":"2017-12-27T00:37:10.000Z","size":96,"stargazers_count":6,"open_issues_count":0,"forks_count":1,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-03-10T18:15:35.088Z","etag":null,"topics":["benchmark","benchmarking","nodejs","performance","performance-analysis","performance-metrics","speed","speedtest"],"latest_commit_sha":null,"homepage":null,"language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/dsfields.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null}},"created_at":"2017-12-10T17:45:34.000Z","updated_at":"2022-01-11T12:25:29.000Z","dependencies_parsed_at":"2023-11-12T00:35:58.616Z","dependency_job_id":"d2cf1970-948f-4961-b0d3-09bd4c77c55b","html_url":"https://github.com/dsfields/radargun","commit_stats":{"total_commits":17,"total_committers":1,"mean_commits":17.0,"dds":0.0,"last_synced_commit":"c0cf2730441e1e454355603c2fd7539b9d552f1a"},"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dsfields%2Fradargun","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dsfields%2Fradargun/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dsfields%2Fradargun/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dsfields%2Fradargun/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/dsfields","download_url":"https://codeload.github.com/dsfields/radargun/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":245227433,"owners_count":20580882,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["benchmark","benchmarking","nodejs","performance","performance-analysis","performance-metrics","speed","speedtest"],"created_at":"2024-10-06T18:06:56.155Z","updated_at":"2025-03-24T07:31:42.270Z","avatar_url":"https://github.com/dsfields.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# radargun\n\n[![Build Status](https://secure.travis-ci.org/dsfields/radargun.svg)](https://travis-ci.org/dsfields/radargun)\n\nEasy to use benchmarking utility for Node.js.  Provides high-precision execution time metrics for: average, min, and max.\n\n__Table of Contents__\n\n* [Usage](#usage)\n* [API](#api)\n* [CLI](#cli)\n* [Benchmarking Very Fast Functions](#benchmarking-very-fast-functions)\n* [CI Pipelines](#ci-pipelines)\n* [Custom Reporter](#custom-reporter)\n\n## Usage\n\n1. Install `radargun` as a dev dependency in your app:\n\n    ```sh\n    $ npm install radargun -D\n    ```\n\n2. Create a `.bench.js` script with a series of functions to benchmark:\n\n    __benchmark/primes.bench.js__\n\n    The `bench()` function is a method added to the global scope by `radargun`.\n\n    ```js\n    bench(\n      [\n        function sieveOfEratosthenes() {\n          // calculate primes to 10000\n        },\n        function sieveOfSundaram() {\n          // calculate primes to 10000\n        }\n      ],\n      { runs: 1000 }\n    );\n    ```\n\n3. Execute your script with `radargun`:\n\n    ```sh\n    $ radargun benchmark/primes.bench.js\n    ```\n\n4. Read the results that are printed to the terminal:\n\n    ```sh\n    ┌──────────────────────┬────────────┬────────────┬────────────┐\n    │ NAME                 │ AVG        │ MIN        │ MAX        │\n    ╞══════════════════════╪════════════╪════════════╪════════════╡\n    │ sieveOfErathosthenes │ 1492392 ns │ 1337675 ns │ 5455338 ns │\n    ├──────────────────────┼────────────┼────────────┼────────────┤\n    │ sieveOfSundaram      │ 802019 ns  │ 688149 ns  │ 3883506 ns │\n    └──────────────────────┴────────────┴────────────┴────────────┘\n    ```\n\n## API\n\n### `bench(functions [, options])`\n\nRuns a benchmark analysis for a given array of functions, and generates a report.\n\n#### Parameters\n\n* `functions`: _(required)_ an array of functions for which to gather performance metrics.  Each function generates its own set of metrics.  Every entry in the array must be a function or an object with the following keys:\n\n  + `bind`: _(optional)_ the `this` context to use while executing the function.  The default is `null`.\n\n  + `fn`: _(required)_ a reference to the function to execute.\n\n  + `label`: _(optional)_ the label to use for this function in the generated report.  The default is the name of the function.\n\n  + `params`: _(optional)_ an array of values to pass into the function.\n\n* `options`: _(optional)_ an object containing keys to customize the behavior of `bench()`.  This object can have the following keys:\n\n  + `reporter`: _(optional)_ a function that is responsible for generating the report.  The default is the built-in reporter.  See [Custom Reporter](#custom-reporter) for more information.\n\n  + `runs`: _(optional)_ the number of times to execute the function.  The default is `10`.\n\n  + `stream`: _(optional)_ a [writable stream](https://nodejs.org/api/stream.html#stream_writable_streams) to which status and report information is written.  The default is `process.stdout`.\n\n  + `thresholds`: _(optional)_ an object that sets performance thresholds for a target function.  A failure to stay within these thresholds will cause the `radargun` utility to exit with `3`.\n\n    All metric thresholds are expressed as a percentage of performance, between the target function and all others (`1 - target/other`) that the target function must meet or exceed.\n\n    - `avg`: _(optional)_ a number specifying the percentage threshold for \"average.\"  If omitted, the target's \"avg\" metric must simply be less than or equal to all other functions.\n\n    - `max`: _(optional)_ a number specifying the percentage threshold for \"max.\"  If omitted, the target's \"max\" metric must simply be less than or equal to all other functions.\n\n    - `min`: _(optional)_ a number specifying the percentage threshold for \"min.\"  If omitted, the target's \"min\" metric must simply be less than or equal to all other functions.\n\n    - `target`: _(required)_ the target function who's benchmark metrics must fall within all specified performance thresholds.  This value is a number specifying an index in the `functions` array.\n\n#### Example\n\n```js\nconst comparisonModule = require('comparison-module');\nconst fs = require('fs');\n\nconst myModule = require('../lib');\n\nconst params = ['foo', 'bar'];\nconst stream = fs.createWriteStream('results.txt');\n\nbench(\n  [\n    {\n      fn: myModule,\n      label: 'My Module',\n      params,\n    },\n    {\n      fn: comparisonModule,\n      label: 'Comparison Module',\n      params,\n    },\n  ],\n  {\n    runs: 1000,\n    stream,\n    thresholds: {\n      avg: 0.5,\n      max: 0.5,\n      min: 0.5,\n      target: 0,\n    },\n  }\n);\n```\n\nIn this example, we are comparing the performance of \"My Module\" against the performance of `comparison-module`.  If My Module's performance is less than 50% greater than that of `comparison-module`, `radargun` exits with error code 3.  Results are writen to a file \"results.txt.\"\n\n## CLI\n\nThe `radargun` command line interface takes a single parameter, which is a [glob](https://en.wikipedia.org/wiki/Glob_(programming)) that specifies how to find bench files to run.\n\n```sh\n$ radargun benchmark/**/*.bench.js\n```\n\n## Benchmarking Very Fast Functions\n\nIn situations where you need to benchmark very fast functions, you get a more accurate understanding of performance by wrapping what it is you want to test in a function, and execute your function in a loop.\n\n```js\nbench(\n  [\n    function () {\n      for (let i = 0; i \u003c 1000000) {\n        myVeryFastFunction();\n      }\n    }\n  ],\n  { runs: 100 }\n);\n```\n\n## CI Pipelines\n\nIt's possible to use `radargun` in a continuous integration pipeline, and fail a build in the event that a new version of your code sees an unacceptable drop in performance.\n\n__Example__\n\n```js\nconst myCurrentModule = require('my-module');\nconst myUpdatedModule = require('../lib');\n\nbench(\n  [\n    {\n      fn: myUpdatedModule,\n      label: 'New Hotness',\n      params: ['foo', 'bar'],\n    },\n    {\n      fn: myCurrentModule,\n      label: 'Currently Published',\n      params: ['foo', 'bar'],\n    },\n  ],\n  {\n    runs: 1000,\n    thresholds: {\n      avg: -0.08,\n      max: -0.08,\n      min: -0.08,\n      target: 0,\n    },\n  }\n);\n```\n\nIn this example, we are comparing the performance of the implementation of `my-module` in the local code base against the published version of `my-module`.  Thresholds are set such that if there is a drop in performance of more than 8%, the `radargun` utility will exit with an error.\n\nKeep in mind that benchmarking is non-deterministic.  It's possible that, depending on conditions with the host, `radargun` could fail with a false negative.  It is recommended that you do some experimentation before settling on thresholds to use in your CI pipeline.\n\n## Custom Reporter\n\nA reporter is a function used to generate a benchmark report.  It is called by the [`bench()`](#bench-functions-options) method after it has completed gathering performance metrics.  The `radargun` module ships with a built-in formater, which functions as the default.  It is possible to provide a custom reporter function as an option to `bench()`.  This function is called with the parameters:\n\n* `stream`: a [writable stream](https://nodejs.org/api/stream.html#stream_writable_streams) to which the report should be written.\n\n* `report`: an array of data containing the performance metrics gathered by the `bench()` method.  Each entry is an object with the keys:\n\n  + `avg`: a number indicating the average execution time (in nanoseconds) of all runs for the function while benchmarking.\n\n  + `label`: a string value indicating the label to use in the report.  This is typically the name of the function\n\n  + `max`: a number indicating the highest execution time (in nanoseconds) encountered for the function while benchmarking.\n\n  + `min`: a number indicating the lowest execution time (in nanoseconds) encountered for the function while benchmarking.\n\n* `thresholds`: if threshold configuration was provided as `options` to the `bench()` method, this value is passed to the reporter.  Otherwise, this value is `null`.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdsfields%2Fradargun","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdsfields%2Fradargun","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdsfields%2Fradargun/lists"}