{"id":13696762,"url":"https://github.com/haensl/js-profiler","last_synced_at":"2025-04-25T07:33:03.144Z","repository":{"id":17219656,"uuid":"81382725","full_name":"haensl/js-profiler","owner":"haensl","description":"JavaScript profiling tool, library and benchmark collection.","archived":false,"fork":false,"pushed_at":"2024-06-16T10:39:59.000Z","size":27551,"stargazers_count":19,"open_issues_count":16,"forks_count":1,"subscribers_count":2,"default_branch":"master","last_synced_at":"2024-10-19T23:43:15.367Z","etag":null,"topics":["ecma","ecmascript","ecmascript6","javascript","nodejs","performance-analysis","performance-testing","profiling","profiling-library"],"latest_commit_sha":null,"homepage":"https://js-profiler.com/","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/haensl.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":".github/FUNDING.yml","license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null},"funding":{"github":["haensl"]}},"created_at":"2017-02-08T22:28:43.000Z","updated_at":"2024-08-06T16:25:29.000Z","dependencies_parsed_at":"2024-04-08T02:51:09.242Z","dependency_job_id":"98fe0520-b7cd-4163-9384-29144416c6f9","html_url":"https://github.com/haensl/js-profiler","commit_stats":{"total_commits":165,"total_committers":7,"mean_commits":"23.571428571428573","dds":0.4181818181818182,"last_synced_commit":"cf08ad0697a9af98b2f078d97467b447308fc732"},"previous_names":[],"tags_count":26,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/haensl%2Fjs-profiler","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/haensl%2Fjs-profiler/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/haensl%2Fjs-profiler/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/haensl%2Fjs-profiler/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/haensl","download_url":"https://codeload.github.com/haensl/js-profiler/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":223881651,"owners_count":17219268,"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":["ecma","ecmascript","ecmascript6","javascript","nodejs","performance-analysis","performance-testing","profiling","profiling-library"],"created_at":"2024-08-02T18:00:46.615Z","updated_at":"2024-11-10T17:36:50.095Z","avatar_url":"https://github.com/haensl.png","language":"JavaScript","funding_links":["https://github.com/sponsors/haensl"],"categories":["3. Application"],"sub_categories":["JavaScript"],"readme":"# [JS-Profiler](https://js-profiler.com)\n\n[\u003cimg src=\"https://js-profiler.com/js-profiler-logo.png\" alt=\"https://js-profiler.com\" width=\"100\" /\u003e](https:/js-profiler.com)\n\nJavaScript profiling tool and library of profiling modules and benchmarks.\n\nJS-Profiler allows you to compare different techniques, operators and functions regarding execution speed and memory consumption. It reports results either in text or JSON format.\n\nJS-Profiler powers [https://js-profiler.com](https://js-profiler.com).\n\n[![NPM](https://nodei.co/npm/js-profiler.png?downloads=true)](https://nodei.co/npm/js-profiler/)\n\n[![CircleCI](https://circleci.com/gh/haensl/js-profiler.svg?style=svg)](https://circleci.com/gh/haensl/js-profiler)\n\n## Table of contents\n\n* [Installation](#installation)\n* [Updates](#updates)\n  * [v2.3.0: New contributor and profile: shallow array copying.](#new-in-v2.3.0)\n  * [v2.2.0: Migrate to Node.js Performance Hooks](#new-in-v2.2.0)\n  * [New in version 2 \u0026 Migration](#new-in-v2)\n    * [Comparison of v1 vs. v2 profile object](#comp-v2-v1-profile)\n      * [v1 profile object](#v1-profile)\n      * [v2 profile object](#v2-profile)\n* [Usage](#usage)\n  * [CLI](#usage-cli)\n  * [Library](#usage-lib)\n* [Profiles](#profiles)\n  * [array concatenation](#array-concat)\n  * [array copying](#array-copy)\n  * [comparison operators](#comparison-operators)\n  * [(de-)composition](#composition)\n  * [guards](#guards)\n  * [loops](#loops)\n  * [map access](#map:access)\n  * [map creation](#map:creation)\n  * [object iteration](#object-iteration)\n  * [recursion](#recursion)\n* [Documentation](docs/index.md)\n* [Changelog](CHANGELOG.md)\n* [License](LICENSE)\n\n## Installation\u003ca name=\"installation\"\u003e\u003c/a\u003e\n\n`npm i [-gS] js-profiler`\n\n## Updates\u003ca name=\"updates\"\u003e\u003c/a\u003e\n\n### [v2.5.0](https://github.com/haensl/js-profiler/releases/tag/v2.5.0): New profile: [(de-)composition.](#composition)\u003ca name=\"new-in-v2.5.0\"\u003e\u003c/a\u003e\n\n### [v2.3.0](https://github.com/haensl/js-profiler/releases/tag/v2.3.0): A new contributor and a new profile: [shallow array copying.](#array-copy)\u003ca name=\"new-in-v2.3.0\"\u003e\u003c/a\u003e\n\nWe are happy to welcome [Josh Howe](https://github.com/joshtch) as a contributor to JS-Profiler! He added a [new profile comparing ways to shallow copy arrays](#array-copy).\n\n##### Big thank you and shout out to [Josh Howe](https://github.com/joshtch)!\n\nDue to updated dependencies, JS-Profiler now requires a minimum Node.js version of 10.12.0.\n\n### [v2.2.0](https://github.com/haensl/js-profiler/releases/tag/v2.2.0): Migrate to [Node.js Performance Hooks](https://nodejs.org/dist/latest-v12.x/docs/api/perf_hooks.html)\u003ca name=\"new-in-v2.2.0\"\u003e\u003c/a\u003e\n\nAs of [version 2.2.0](https://github.com/haensl/js-profiler/releases/tag/v2.2.0) js-profiler gathers function timing information via the [Performance Hooks API](https://nodejs.org/dist/latest-v12.x/docs/api/perf_hooks.html) instead of [process.hrtime()](https://nodejs.org/dist/latest-v12.x/docs/api/process.html#process_process_hrtime_time).\n\n### New in version 2 \u0026 Migration from v1.x.y to v2.x.y\u003ca name=\"new-in-v2\"\u003e\u003c/a\u003e\n\n* `profile.tests` is renamed to `profile.functions`\n* `function.description` _(formerly `test.description`)_ now contains a _nice_ human readable description.\n* `function.codeSample` now contains a short pseudo-code sample of the function under test.\n* use `function.code` to access the full source code of the function under test.\n* `function.keywords` contains keywords associated with the function under test.\n* `profile.keywords` contains keywords associated with this profile.\n\n#### Comparison of a v1 vs. v2 profile object\u003ca name=\"comp-v2-v1-profile\"\u003e\u003c/a\u003e\n\n##### Version 1.x.y profile object\u003ca name=\"v1-profile\"\u003e\u003c/a\u003e\n\n```javascript\n// v1\n{\n  \"name\" : \"recursion\",\n  \"description\" : \"Recursion variations: Calculating sum of array of integers. Profile contains a simple for-loop for reference.\",\n  \"tests\" : [\n      {\n          \"description\" : \"for loop sum for reference\",\n          \"time\" : {\n              \"average\" : \"1.4923μs\",\n              \"minimum\" : \"1.0970μs\",\n              \"maximum\" : \"38.8230μs\"\n          }\n      }, \n      {\n          \"description\" : \"recursive sum\",\n          \"time\" : {\n              \"average\" : \"1080.3024μs\",\n              \"minimum\" : \"703.3320μs\",\n              \"maximum\" : \"10215.1650μs\"\n          }\n      }, \n      {\n          \"description\" : \"tail recursive sum\",\n          \"time\" : {\n              \"average\" : \"1041.0375μs\",\n              \"minimum\" : \"704.2790μs\",\n              \"maximum\" : \"16476.7110μs\"\n          }\n      }\n  ],\n  \"fastest\" : [\n      {\n          \"description\" : \"for loop sum for reference\",\n          \"time\" : {\n              \"average\" : \"1.4923μs\",\n              \"minimum\" : \"1.0970μs\",\n              \"maximum\" : \"38.8230μs\"\n          }\n      }\n  ]\n}\n```\n\n##### Version 2.x.y profile object\u003ca name=\"v2-profile\"\u003e\u003c/a\u003e\n\n```javascript\n// v2\n{\n  \"name\": \"recursion\",\n  \"description\": \"Recursion.\",\n  \"keywords\": [\n    \"for\",\n    \"loop\",\n    \"recursion\",\n    \"sum\",\n    \"tail\",\n    \"tailrecursion\"\n  ],\n  \"functions\": [\n    {\n      \"description\": \"for loop sum for reference\",\n      \"keywords\": [\n        \"for\",\n        \"loop\",\n        \"sum\"\n      ],\n      \"codeSample\": \"for (...) { sum += d[i] }\",\n      \"code\": \"(d) =\u003e {\\n    let sum = 0;\\n    for (let i = 0; i \u003c d.length; i++) {\\n      sum += d[i];\\n    }\\n\\n    return sum;\\n  }\",\n      \"time\": {\n        \"average\": \"3.8774µs\"\n      }\n    },\n    {\n      \"description\": \"recursive sum\",\n      \"keywords\": [\n        \"recursion\",\n        \"sum\"\n      ],\n      \"codeSample\": \"const f = (d) =\u003e (d \u0026\u0026 d.length \u0026\u0026 (d[0] + f(d.slice(1)))) || 0\",\n      \"code\": \"(d) =\u003e (d \u0026\u0026 d.length \u0026\u0026 (d[0] + recursiveSum.f(d.slice(1)))) || 0\",\n      \"time\": {\n        \"average\": \"733.7537µs\"\n      }\n    },\n    {\n      \"description\": \"tail recursive sum\",\n      \"keywords\": [\n        \"recursion\",\n        \"sum\",\n        \"tail\",\n        \"tailrecursion\"\n      ],\n      \"codeSample\": \"const f = (d, i = 0) =\u003e (!d.length \u0026\u0026 i) || f(d.slice(1), i + d[0])\",\n      \"code\": \"(d, i = 0) =\u003e (!d.length \u0026\u0026 i)\\n    || tailRecursiveSum.f(d.slice(1), i + d[0])\",\n      \"time\": {\n        \"average\": \"769.7328µs\"\n      }\n    }\n  ],\n  \"fastest\": [\n    {\n      \"description\": \"for loop sum for reference\",\n      \"keywords\": [\n        \"for\",\n        \"loop\",\n        \"sum\"\n      ],\n      \"codeSample\": \"for (...) { sum += d[i] }\",\n      \"code\": \"(d) =\u003e {\\n    let sum = 0;\\n    for (let i = 0; i \u003c d.length; i++) {\\n      sum += d[i];\\n    }\\n\\n    return sum;\\n  }\",\n      \"time\": {\n        \"average\": \"3.8774µs\"\n      }\n    }\n  ]\n}\n```\n\n## Usage\u003ca name=\"usage\"\u003e\u003c/a\u003e\n\n### CLI\u003ca name=\"usage-cli\"\u003e\u003c/a\u003e\n\nIf installed with the `-g` flag you can simply run js-profiler from your command line:\n\n![Intro](intro.gif)\n\nFor further information please refer to the [CLI documentation](docs/cli.md) and the man page.\n\n### Library\u003ca name=\"usage-lib\"\u003e\u003c/a\u003e\n\n```javascript\n// 1. Import the library\nconst jsProfiler = require('js-profiler');\n\n// 2. Run the profiler\njsProfiler.run()\n  .then((report) =\u003e {\n    console.log(JSON.stringify(report, null, 2));\n  });\n```\n\nFor configuration options please refer to the [Library documentation](docs/lib.md).\n\n## Available performance profiles:\u003ca name=\"profiles\"\u003e\u003c/a\u003e\n\n### [array concatenation](https://js-profiler.com/#array-concatenation)\u003ca name=\"array-concat\"\u003e\u003c/a\u003e\nArray concatenation variations: Combining two arrays using different techniques.\n\nProfiled operations:\n  * `a.concat(b)`\n  * `for (...) { a.push(b[i])}`\n  * `for (...) { b.unshift(a[i])}`\n  * `a.push.apply(a, b)`\n  * `Array.prototype.unshift.apply(b, a)`\n  * `b.reduce((arr, item) =\u003e arr.push(item), a)`\n  * `a.reduceRight((arr, item) =\u003e arr.unshift(item), b)`\n  * `[...a, ...b]`\n\n### [array copying](https://js-profiler.com/#array-copying)\u003ca name=\"array-copy\"\u003e\u003c/a\u003e\nArray copying variations: creating a new array with the same elements as an existing array.\n\nProfiled operations:\n  * `a.slice()`\n  * `[...a]`\n  * `Array.from(a)`\n  * `new Array(...a)`\n  * `a.concat([])`\n  * `[].concat(a)`\n  * `Array.prototype.unshift.apply([], a)`\n  * `Array.prototype.unshift.apply(new Arrray(), a)`\n  * `[].push(...a)`\n  * `(new Array()).push(...a)`\n  * `b = []; for(...){ b.push(a[i]) }`\n  * `b = new Array(); for(...){ b.push(a[i]) }`\n  * `b = new Array(a.length); for(...){ b[i] = a[i] }`\n\n### [(de-)composition](https://js-profiler.com/#de-composition)\u003ca name=\"composition\"\u003e\u003c/a\u003e\n(De-)Composition: composing objects, arrays and variables from each other.\n\nProfiled operations:\n  * `const { a, b } = obj`\n  * `const { a = i } = obj`\n  * `const [a, b] = arr`\n  * `const [a = i, b] = d`\n  * `const [a, b, ...tail] = d`\n  * `const a = arr[i]`\n  * `const a = arr[i] || j`\n  * `const a = obj.b`\n  * `const a = obj.b || i`\n  * `const [a, b] = [b, a]`\n  * `const c = b; b = a; a = c`\n\n### [comarison operators](https://js-profiler.com/#comparison-operators)\u003ca name=\"comparison-operators\"\u003e\u003c/a\u003e\nVariable comparison operators.\n\nProfiled operations:\n  * `a \u003e b`\n  * `a \u003e= b`\n  * `a \u003c b`\n  * `a \u003c= b`\n  * `==`\n  * `===`\n  * `!=`\n  * `!==`\n  * `\u0026\u0026`\n  * ||\n\n### [guards](https://js-profiler.com/#guards)\u003ca name=\"guards\"\u003e\u003c/a\u003e\nVariable guards: checking whether a variable is defined or of a certain type.\n\nProfiled operations:\n  * `typeof !== 'undefined'`\n  * `typeof != 'undefined'`\n  * `typeof === 'function'`\n  * `typeof == 'function'`\n  * `typeof === 'number'`\n  * `typeof == 'number'`\n  * `typeof === 'object'`\n  * `typeof == 'object'`\n  * `typeof === 'string'`\n  * `typeof == 'string'`\n  * `Array.isArray`\n  * `!!var`\n  * `!var`\n  * `isNaN(var)`\n  * `Number.isNaN(var)`\n  * `!isNaN(var)`\n  * `!Number.IsNaN(var)`\n  * `prop in obj`\n  * `obj.hasOwnProperty(prop)`\n  * `Object.prototype.hasOwnProperty.call(obj, prop)`\n\n### [loops](https://js-profiler.com/#loops)\u003ca name=\"loops\"\u003e\u003c/a\u003e\nLoop variations: Converting an array of integers into an array of booleans satisfying a conjunction of two simple relational operations.\n\nProfiled operations:\n  * `[].forEach() =\u003e []`\n  * `for(i++, i \u003c d.length) =\u003e []`\n  * `for(i++, i \u003c len) =\u003e []`\n  * `while(i--) =\u003e []`\n  * `[].map() =\u003e []`\n  * `while(i \u003c d.length) =\u003e []`\n  * `while(i \u003c len) =\u003e []`\n  * `do { } while (i \u003c d.length)`\n  * `do { } while (i \u003c len)`\n  * `for (prop of [])`\n\n### [map access](https://js-profiler.com/#map:access)\u003ca name=\"map:access\"\u003e\u003c/a\u003e\nObject literal vs. Map: retrieving values.\n\nProfiled operations:\n  * `Map.get()`\n  * `{}.prop`\n\n### [map creation](https://js-profiler.com/#map:creation)\u003ca name=\"map:creation\"\u003e\u003c/a\u003e\nObject literal vs. Map: creating a map.\n\nProfiled operations:\n  * `Map.set()`\n  * `new Map([props])`\n  * `{}.prop = val`\n  * `Object.defineProperty({}, prop, desc)`\n  * `Object.defineProperties({}, props)`\n  * `{ ...props }`\n\n### [object iteration](https://js-profiler.com/#object-iteration)\u003ca name=\"object-iteration\"\u003e\u003c/a\u003e\nObject iteration: different ways of iterating over properties of an object and concatenating property names into a single string.\n\nProfiled operations:\n  * `for (const prop in obj) {}`\n  * `Object.keys(obj).forEach()`\n  * `Object.entries(obj).forEach()`\n  * `for (prop of Map.keys())`\n  * `for (prop of Object.keys(obj))`\n  * `for (prop of Object.keys(obj) { obj.hasOwnProperty(prop) \u0026\u0026 ... })`\n  * `for (prop of Object.getOwnPropertyNames(obj))`\n  * `Object.getOwnPropertyNames(obj).forEach()`\n\n### [recursion](https://js-profiler.com/#recursion)\u003ca name=\"recursion\"\u003e\u003c/a\u003e\nRecurstion variations: Calculating sum of array of integers. Profile contains a simple for-loop for reference.\n\nProfiled operations:\n  * `for loop sum for reference`\n  * `recursive sum`\n  * `tail recursive sum`\n\n## [Documentation](docs/index.md)\n\n## [Changelog](CHANGELOG.md)\n\n## [License](LICENSE)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fhaensl%2Fjs-profiler","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fhaensl%2Fjs-profiler","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fhaensl%2Fjs-profiler/lists"}