extra-benchmark 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2022 BlackGlory <woshenmedoubuzhidao@blackglory.me>
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,97 @@
1
+ # extra-benchmark
2
+ Lightweight benchmarking library.
3
+
4
+ ## Install
5
+ ```sh
6
+ npm install --save extra-benchmark
7
+ # or
8
+ yarn add extra-benchmark
9
+ ```
10
+
11
+ ## Usage
12
+ ```ts
13
+ import { Benchmark } from 'extra-benchmark'
14
+
15
+ const benchmark = new Benchmark('Swap')
16
+
17
+ benchmark.addCase('Bit-based computing', () => {
18
+ let a = 0
19
+ let b = 1
20
+
21
+ return () => {
22
+ a = a ^ b
23
+ b = a ^ b
24
+ a = a ^ b
25
+ }
26
+ })
27
+
28
+ benchmark.addCase('Use a temporary variable', () => {
29
+ let a = 0
30
+ let b = 1
31
+
32
+ return () => {
33
+ const temp = a
34
+ a = b
35
+ b = temp
36
+ }
37
+ })
38
+
39
+ console.log(benchmark.name)
40
+ for await (const result of benchmark.run()) {
41
+ console.log(result)
42
+ }
43
+ ```
44
+
45
+ ## API
46
+ ```ts
47
+ interface IBenchmarkOptions {
48
+ /* The number of times to warm up the benchmark test */
49
+ warmUps?: number
50
+
51
+ /* The number of times to run the benchmark test */
52
+ runs?: number
53
+ }
54
+
55
+ interface IBenchmarkCaseResult {
56
+ name: string
57
+ warmUps: number
58
+ runs: number
59
+
60
+ operationsPerSecond: number
61
+ operationsPerMillisecond: number
62
+ operationsPerNanosecond: number
63
+
64
+ /* Milliseconds */
65
+ maxiumElapsedTime: bigint
66
+ minimumElapsedTime: bigint
67
+ averageElapsedTime: bigint
68
+
69
+ /* Bytes */
70
+ maximumMemoryIncrements: number
71
+ minimumMemoryIncrements: number
72
+ averageMemoryIncrements: number
73
+ }
74
+ ```
75
+
76
+ ### Benchmark
77
+ ```ts
78
+ class Benchmark {
79
+ readonly name: string
80
+
81
+ constructor(
82
+ name: string
83
+ , {
84
+ warmUps: 100
85
+ , runs: 100
86
+ }: IBenchmarkOptions = {}
87
+ )
88
+
89
+ addCase(
90
+ name: string
91
+ , fn: () => Awaitable<() => Awaitable<void>>
92
+ , options?: IBenchmarkResult
93
+ ): void
94
+
95
+ run(): AsyncIterable<IBenchmarkCaseResult>
96
+ }
97
+ ```
@@ -0,0 +1,28 @@
1
+ import { Awaitable } from '@blackglory/prelude';
2
+ export interface IBenchmarkOptions {
3
+ warmUps?: number;
4
+ runs?: number;
5
+ }
6
+ export interface IBenchmarkCaseResult {
7
+ name: string;
8
+ warmUps: number;
9
+ runs: number;
10
+ operationsPerSecond: number;
11
+ operationsPerMillisecond: number;
12
+ operationsPerNanosecond: number;
13
+ maxiumElapsedTime: bigint;
14
+ minimumElapsedTime: bigint;
15
+ averageElapsedTime: bigint;
16
+ maximumMemoryIncrements: number;
17
+ minimumMemoryIncrements: number;
18
+ averageMemoryIncrements: number;
19
+ }
20
+ export declare class Benchmark {
21
+ readonly name: string;
22
+ private benchmarkCases;
23
+ private warmUps;
24
+ private runs;
25
+ constructor(name: string, options?: IBenchmarkOptions);
26
+ addCase(name: string, fn: () => Awaitable<() => Awaitable<void>>, options?: IBenchmarkOptions): void;
27
+ run(): AsyncIterable<IBenchmarkCaseResult>;
28
+ }
@@ -0,0 +1,85 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.Benchmark = void 0;
4
+ const prelude_1 = require("@blackglory/prelude");
5
+ class Benchmark {
6
+ constructor(name, options = {}) {
7
+ this.name = name;
8
+ this.benchmarkCases = [];
9
+ this.warmUps = options.warmUps ?? 100;
10
+ this.runs = options.runs ?? 100;
11
+ }
12
+ addCase(name, fn, options = {}) {
13
+ this.benchmarkCases.push({ name, fn, options });
14
+ }
15
+ async *run() {
16
+ for (const benchmarkCase of this.benchmarkCases) {
17
+ const { fn, name, options } = benchmarkCase;
18
+ const iterate = await fn();
19
+ const warmUps = options.warmUps ?? this.warmUps;
20
+ const runs = options.runs ?? this.runs;
21
+ for (let i = warmUps; i--;) {
22
+ await iterate();
23
+ }
24
+ const samples = [];
25
+ for (let i = runs; i--;) {
26
+ const startRSS = process.memoryUsage().rss;
27
+ const startTime = process.hrtime.bigint();
28
+ await iterate();
29
+ const endTime = process.hrtime.bigint();
30
+ const elapsedTime = endTime - startTime;
31
+ const endRSS = process.memoryUsage().rss;
32
+ const memoryIncrements = endRSS - startRSS;
33
+ samples.push({
34
+ elapsedTime,
35
+ memoryIncrements
36
+ });
37
+ }
38
+ const elapsedTimes = samples.map(x => x.elapsedTime);
39
+ const maxiumElapsedTime = elapsedTimes.reduce((max, cur) => cur > max ? cur : max);
40
+ const minimumElapsedTime = elapsedTimes.reduce((min, cur) => cur > min ? min : cur);
41
+ const totalElapsedTime = elapsedTimes.reduce((acc, cur) => acc + cur);
42
+ const averageElapsedTime = totalElapsedTime / BigInt(runs);
43
+ const { operationsPerNanosecond, operationsPerMillisecond, operationsPerSecond } = (0, prelude_1.go)(() => {
44
+ if (totalElapsedTime <= Number.MAX_SAFE_INTEGER) {
45
+ const operationsPerNanosecond = runs / Number(totalElapsedTime);
46
+ const operationsPerMillisecond = runs / (Number(totalElapsedTime) / 1000000);
47
+ const operationsPerSecond = runs / (Number(totalElapsedTime) / 1000000 / 1000);
48
+ return { operationsPerSecond, operationsPerMillisecond, operationsPerNanosecond };
49
+ }
50
+ else {
51
+ const operationsPerNanosecond = Number(BigInt(runs) / totalElapsedTime);
52
+ const operationsPerMillisecond = runs / Number(totalElapsedTime / 1000000n);
53
+ const operationsPerSecond = runs / (Number(totalElapsedTime / 1000000n) / 1000);
54
+ return { operationsPerSecond, operationsPerMillisecond, operationsPerNanosecond };
55
+ }
56
+ });
57
+ const memoryIncrments = samples.map(x => x.memoryIncrements);
58
+ const maximumMemoryIncrements = memoryIncrments.reduce((max, cur) => {
59
+ return cur > max ? cur : max;
60
+ });
61
+ const minimumMemoryIncrements = memoryIncrments.reduce((min, cur) => {
62
+ return cur > min ? min : cur;
63
+ });
64
+ const averageMemoryIncrements = memoryIncrments.reduce((average, cur) => {
65
+ return (average + cur) / 2;
66
+ });
67
+ yield {
68
+ name,
69
+ warmUps,
70
+ runs,
71
+ operationsPerSecond,
72
+ operationsPerMillisecond,
73
+ operationsPerNanosecond,
74
+ maxiumElapsedTime,
75
+ minimumElapsedTime,
76
+ averageElapsedTime,
77
+ maximumMemoryIncrements,
78
+ averageMemoryIncrements,
79
+ minimumMemoryIncrements
80
+ };
81
+ }
82
+ }
83
+ }
84
+ exports.Benchmark = Benchmark;
85
+ //# sourceMappingURL=benchmark.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"benchmark.js","sourceRoot":"","sources":["../src/benchmark.ts"],"names":[],"mappings":"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"}
package/lib/index.d.ts ADDED
@@ -0,0 +1 @@
1
+ export * from './benchmark';
package/lib/index.js ADDED
@@ -0,0 +1,18 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
+ };
16
+ Object.defineProperty(exports, "__esModule", { value: true });
17
+ __exportStar(require("./benchmark"), exports);
18
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,8CAA2B"}
package/package.json ADDED
@@ -0,0 +1,59 @@
1
+ {
2
+ "name": "extra-benchmark",
3
+ "version": "0.1.0",
4
+ "description": "Lightweight benchmarking library.",
5
+ "keywords": [],
6
+ "files": [
7
+ "lib",
8
+ "dist"
9
+ ],
10
+ "main": "lib/index.js",
11
+ "types": "lib/index.d.ts",
12
+ "sideEffects": false,
13
+ "repository": "git@github.com:BlackGlory/extra-benchmark.git",
14
+ "author": "BlackGlory <woshenmedoubuzhidao@blackglory.me>",
15
+ "license": "MIT",
16
+ "scripts": {
17
+ "lint": "eslint --ext .js,.jsx,.ts,.tsx --quiet src __tests__",
18
+ "test": "jest --runInBand --config jest.config.js",
19
+ "test:debug": "node --inspect-brk node_modules/.bin/jest --runInBand",
20
+ "test:coverage": "jest --coverage --config jest.config.js",
21
+ "prepublishOnly": "run-s clean build",
22
+ "clean": "rimraf lib",
23
+ "build": "run-p build:*",
24
+ "build:compile": "tsc --project tsconfig.build.json --module commonjs",
25
+ "build:patch": "tscpaths -p tsconfig.build.json -s ./src -o ./lib",
26
+ "bench": "./benches/benchmark.sh",
27
+ "release": "standard-version"
28
+ },
29
+ "husky": {
30
+ "hooks": {
31
+ "pre-commit": "run-s lint build test",
32
+ "commit-msg": "commitlint -E HUSKY_GIT_PARAMS"
33
+ }
34
+ },
35
+ "devDependencies": {
36
+ "@blackglory/jest-matchers": "^0.3.1",
37
+ "@commitlint/cli": "^17.0.3",
38
+ "@commitlint/config-conventional": "^17.0.3",
39
+ "@types/jest": "^27.4.1",
40
+ "@types/node": "^18.7.13",
41
+ "@typescript-eslint/eslint-plugin": "^5.35.1",
42
+ "@typescript-eslint/parser": "^5.35.1",
43
+ "eslint": "^8.22.0",
44
+ "husky": "^4.3.8",
45
+ "iterable-operator": "^1.2.1",
46
+ "jest": "^27.5.1",
47
+ "npm-run-all": "^4.1.5",
48
+ "return-style": "^1.0.0",
49
+ "rimraf": "^3.0.2",
50
+ "standard-version": "^9.5.0",
51
+ "ts-jest": "^27.1.4",
52
+ "tscpaths": "^0.0.9",
53
+ "tslib": "^2.3.1",
54
+ "typescript": "^4.8.2"
55
+ },
56
+ "dependencies": {
57
+ "@blackglory/prelude": "^0.1.4"
58
+ }
59
+ }