From 11d42b4ecbbb6527bc1b1b17660afefe7fea61eb Mon Sep 17 00:00:00 2001 From: Vladislav Mamon Date: Sat, 14 May 2022 12:30:04 +0500 Subject: [PATCH] perf(no-release): refactor benchmarks & add another bench --- benchmarks/README.md | 8 +- benchmarks/package-lock.json | 255 ++++++++++++++++++++++++++++--- benchmarks/package.json | 18 ++- benchmarks/src/@helpers/index.ts | 22 +++ benchmarks/src/index.ts | 1 + benchmarks/src/json/index.ts | 14 +- benchmarks/src/json/sigma.ts | 14 +- benchmarks/src/many/@sample.ts | 12 ++ benchmarks/src/many/index.ts | 16 ++ benchmarks/src/many/parjs.ts | 16 ++ benchmarks/src/many/sigma.ts | 20 +++ benchmarks/src/tuple/index.ts | 14 +- benchmarks/src/tuple/sigma.ts | 6 +- benchmarks/tsconfig.json | 2 +- 14 files changed, 354 insertions(+), 64 deletions(-) create mode 100644 benchmarks/src/@helpers/index.ts create mode 100644 benchmarks/src/many/@sample.ts create mode 100644 benchmarks/src/many/index.ts create mode 100644 benchmarks/src/many/parjs.ts create mode 100644 benchmarks/src/many/sigma.ts diff --git a/benchmarks/README.md b/benchmarks/README.md index b11ef00..eb0551c 100644 --- a/benchmarks/README.md +++ b/benchmarks/README.md @@ -6,18 +6,18 @@ Here you will find some benchmarks and rough performance comparison with similar Unfortunately, it's difficult to come up with sensible benchmarks, given that how a parser written with **sigma** depends entirely on what you are parsing, how you structure your parser(s), which patterns the parser attempts to match first, what is involved in constructing your AST (if any), and so on. -All that said, here are some rough numbers from the [JSON parsing benchmark][json-bench] (running on my MacBook Pro 16" with `Intel i9-9880H @ 2.30GHz` and `Node@14`). +All that said, here are some rough numbers from the [JSON parsing benchmark][json-bench] (running on my MacBook Pro 16" 2019 with `Intel i9-9880H @ 2.30GHz` and `Node@16.13`). ```hs Running "JSON :: sigma vs parjs" suite... - sigma: 582 ops/s, ±1.12% | fastest - parjs: 138 ops/s, ±1.38% | slowest, 76.29% slower + sigma: 762 ops/s, ±0.82% | fastest + parjs: 134 ops/s, ±0.63% | slowest, 82.41% slower ``` I have included results from [Sigma] and [Parjs] (another parser combinator library). I wanted to also add [Arcsecond], because I like its API with functional flavor, but somehow their JSON example is _atrociously_ slow (like, orders of magnitude, 250-500 times slower). -The [JSON sample][json-sample] being parsed is a typical JSON data, which has 923 lines. This translates to ~530k lines of JSON per second, and that is actually on par with some Rust parser combinator crates like [pom]. +The [JSON sample][json-sample] being parsed is a typical JSON data, which has 923 lines. This translates to **~700k** lines of JSON per second, and that is actually on par with some Rust parser combinator crates like [pom]. diff --git a/benchmarks/package-lock.json b/benchmarks/package-lock.json index 2183947..a0d33bc 100644 --- a/benchmarks/package-lock.json +++ b/benchmarks/package-lock.json @@ -8,14 +8,15 @@ "name": "@nrsk/sigma-benchmarks", "version": "1.0.0", "dependencies": { - "@nrsk/sigma": "2.0.0", + "@nrsk/sigma": "2.0.2", "benny": "^3.7.1", "parjs": "0.12.7" }, "devDependencies": { "@types/benchmark": "^2.1.1", - "@types/node": "^14.18.0", - "typescript": "^4.5.5" + "@types/node": "^14.18.18", + "rimraf": "^3.0.2", + "typescript": "^4.6.4" } }, "node_modules/@arrows/array": { @@ -56,9 +57,9 @@ } }, "node_modules/@nrsk/sigma": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/@nrsk/sigma/-/sigma-2.0.0.tgz", - "integrity": "sha512-KC8agPrIBwmCH7Ws63GUOwwaXWGMJVoyXzazdd+4BmEvJJ8SU6bARgnvasErwn2aMztqYrnAYQQHydeUMI81Yw==", + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/@nrsk/sigma/-/sigma-2.0.2.tgz", + "integrity": "sha512-Zx5RruNXmCop8L4YLhgCpD5dAqQ9oNCJYrwKcimTbCk7riejg4oIs9dLCCJUoYgcpkNja3n1Qt7XWyCvWN1XNg==", "engines": { "node": ">=14.17.0" } @@ -70,9 +71,9 @@ "dev": true }, "node_modules/@types/node": { - "version": "14.18.9", - "resolved": "https://registry.npmjs.org/@types/node/-/node-14.18.9.tgz", - "integrity": "sha512-j11XSuRuAlft6vLDEX4RvhqC0KxNxx6QIyMXNb0vHHSNPXTPeiy3algESWmOOIzEtiEL0qiowPU3ewW9hHVa7Q==", + "version": "14.18.18", + "resolved": "https://registry.npmjs.org/@types/node/-/node-14.18.18.tgz", + "integrity": "sha512-B9EoJFjhqcQ9OmQrNorItO+OwEOORNn3S31WuiHvZY/dm9ajkB7AKD/8toessEtHHNL+58jofbq7hMMY9v4yig==", "dev": true }, "node_modules/ansi-escapes": { @@ -119,6 +120,12 @@ "node": ">=8" } }, + "node_modules/balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "dev": true + }, "node_modules/benchmark": { "version": "2.1.4", "resolved": "https://registry.npmjs.org/benchmark/-/benchmark-2.1.4.tgz", @@ -147,6 +154,16 @@ "node": ">=12" } }, + "node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, "node_modules/char-info": { "version": "0.3.2", "resolved": "https://registry.npmjs.org/char-info/-/char-info-0.3.2.tgz", @@ -198,6 +215,12 @@ "node": ">=4.0.0" } }, + "node_modules/concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", + "dev": true + }, "node_modules/emoji-regex": { "version": "8.0.0", "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", @@ -221,11 +244,53 @@ "node": ">=12" } }, + "node_modules/fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", + "dev": true + }, + "node_modules/glob": { + "version": "7.2.2", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.2.tgz", + "integrity": "sha512-NzDgHDiJwKYByLrL5lONmQFpK/2G78SMMfo+E9CuGlX4IkvfKDsiQSNPwAYxEy+e6p7ZQ3uslSLlwlJcqezBmQ==", + "dev": true, + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, "node_modules/graceful-fs": { "version": "4.2.9", "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.9.tgz", "integrity": "sha512-NtNxqUcXgpW2iMrfqSfR73Glt39K+BLwWsPs94yR63v45T0Wbej7eRmL5cWfwEgqXnmjQp3zaJTshdRW/qC2ZQ==" }, + "node_modules/inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", + "dev": true, + "dependencies": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "node_modules/inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "dev": true + }, "node_modules/is-fullwidth-code-point": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", @@ -313,6 +378,18 @@ "node": ">=6" } }, + "node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, "node_modules/node-interval-tree": { "version": "1.3.3", "resolved": "https://registry.npmjs.org/node-interval-tree/-/node-interval-tree-1.3.3.tgz", @@ -324,6 +401,15 @@ "node": ">= 7.6.0" } }, + "node_modules/once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", + "dev": true, + "dependencies": { + "wrappy": "1" + } + }, "node_modules/onetime": { "version": "5.1.2", "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", @@ -347,6 +433,15 @@ "lodash": "^4.17.13" } }, + "node_modules/path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/platform": { "version": "1.3.6", "resolved": "https://registry.npmjs.org/platform/-/platform-1.3.6.tgz", @@ -364,6 +459,21 @@ "node": ">=8" } }, + "node_modules/rimraf": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", + "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", + "dev": true, + "dependencies": { + "glob": "^7.1.3" + }, + "bin": { + "rimraf": "bin.js" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, "node_modules/shallowequal": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/shallowequal/-/shallowequal-1.1.0.tgz", @@ -426,9 +536,9 @@ } }, "node_modules/typescript": { - "version": "4.5.5", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.5.5.tgz", - "integrity": "sha512-TCTIul70LyWe6IJWT8QSYeA54WQe8EjQFU4wY52Fasj5UKx88LNYKCgBEHcOMOrFF1rKGbD8v/xcNWVUq9SymA==", + "version": "4.6.4", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.6.4.tgz", + "integrity": "sha512-9ia/jWHIEbo49HfjrLGfKbZSuWo9iTMwXO+Ca3pRsSpbsMbc7/IU8NKdCZVRRBafVPGnoJeFL76ZOAA84I9fEg==", "dev": true, "bin": { "tsc": "bin/tsc", @@ -458,6 +568,12 @@ "engines": { "node": ">=8" } + }, + "node_modules/wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", + "dev": true } }, "dependencies": { @@ -499,9 +615,9 @@ } }, "@nrsk/sigma": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/@nrsk/sigma/-/sigma-2.0.0.tgz", - "integrity": "sha512-KC8agPrIBwmCH7Ws63GUOwwaXWGMJVoyXzazdd+4BmEvJJ8SU6bARgnvasErwn2aMztqYrnAYQQHydeUMI81Yw==" + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/@nrsk/sigma/-/sigma-2.0.2.tgz", + "integrity": "sha512-Zx5RruNXmCop8L4YLhgCpD5dAqQ9oNCJYrwKcimTbCk7riejg4oIs9dLCCJUoYgcpkNja3n1Qt7XWyCvWN1XNg==" }, "@types/benchmark": { "version": "2.1.1", @@ -510,9 +626,9 @@ "dev": true }, "@types/node": { - "version": "14.18.9", - "resolved": "https://registry.npmjs.org/@types/node/-/node-14.18.9.tgz", - "integrity": "sha512-j11XSuRuAlft6vLDEX4RvhqC0KxNxx6QIyMXNb0vHHSNPXTPeiy3algESWmOOIzEtiEL0qiowPU3ewW9hHVa7Q==", + "version": "14.18.18", + "resolved": "https://registry.npmjs.org/@types/node/-/node-14.18.18.tgz", + "integrity": "sha512-B9EoJFjhqcQ9OmQrNorItO+OwEOORNn3S31WuiHvZY/dm9ajkB7AKD/8toessEtHHNL+58jofbq7hMMY9v4yig==", "dev": true }, "ansi-escapes": { @@ -541,6 +657,12 @@ "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-2.0.0.tgz", "integrity": "sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ==" }, + "balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "dev": true + }, "benchmark": { "version": "2.1.4", "resolved": "https://registry.npmjs.org/benchmark/-/benchmark-2.1.4.tgz", @@ -566,6 +688,16 @@ "log-update": "^4.0.0" } }, + "brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "requires": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, "char-info": { "version": "0.3.2", "resolved": "https://registry.npmjs.org/char-info/-/char-info-0.3.2.tgz", @@ -605,6 +737,12 @@ "resolved": "https://registry.npmjs.org/common-tags/-/common-tags-1.8.2.tgz", "integrity": "sha512-gk/Z852D2Wtb//0I+kRFNKKE9dIIVirjoqPoA1wJU+XePVXZfGeBpk45+A1rKO4Q43prqWBNY/MiIeRLbPWUaA==" }, + "concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", + "dev": true + }, "emoji-regex": { "version": "8.0.0", "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", @@ -625,11 +763,47 @@ "universalify": "^2.0.0" } }, + "fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", + "dev": true + }, + "glob": { + "version": "7.2.2", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.2.tgz", + "integrity": "sha512-NzDgHDiJwKYByLrL5lONmQFpK/2G78SMMfo+E9CuGlX4IkvfKDsiQSNPwAYxEy+e6p7ZQ3uslSLlwlJcqezBmQ==", + "dev": true, + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + }, "graceful-fs": { "version": "4.2.9", "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.9.tgz", "integrity": "sha512-NtNxqUcXgpW2iMrfqSfR73Glt39K+BLwWsPs94yR63v45T0Wbej7eRmL5cWfwEgqXnmjQp3zaJTshdRW/qC2ZQ==" }, + "inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", + "dev": true, + "requires": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "dev": true + }, "is-fullwidth-code-point": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", @@ -690,6 +864,15 @@ "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==" }, + "minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "requires": { + "brace-expansion": "^1.1.7" + } + }, "node-interval-tree": { "version": "1.3.3", "resolved": "https://registry.npmjs.org/node-interval-tree/-/node-interval-tree-1.3.3.tgz", @@ -698,6 +881,15 @@ "shallowequal": "^1.0.2" } }, + "once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", + "dev": true, + "requires": { + "wrappy": "1" + } + }, "onetime": { "version": "5.1.2", "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", @@ -715,6 +907,12 @@ "lodash": "^4.17.13" } }, + "path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", + "dev": true + }, "platform": { "version": "1.3.6", "resolved": "https://registry.npmjs.org/platform/-/platform-1.3.6.tgz", @@ -729,6 +927,15 @@ "signal-exit": "^3.0.2" } }, + "rimraf": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", + "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", + "dev": true, + "requires": { + "glob": "^7.1.3" + } + }, "shallowequal": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/shallowequal/-/shallowequal-1.1.0.tgz", @@ -773,9 +980,9 @@ "integrity": "sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==" }, "typescript": { - "version": "4.5.5", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.5.5.tgz", - "integrity": "sha512-TCTIul70LyWe6IJWT8QSYeA54WQe8EjQFU4wY52Fasj5UKx88LNYKCgBEHcOMOrFF1rKGbD8v/xcNWVUq9SymA==", + "version": "4.6.4", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.6.4.tgz", + "integrity": "sha512-9ia/jWHIEbo49HfjrLGfKbZSuWo9iTMwXO+Ca3pRsSpbsMbc7/IU8NKdCZVRRBafVPGnoJeFL76ZOAA84I9fEg==", "dev": true }, "universalify": { @@ -792,6 +999,12 @@ "string-width": "^4.1.0", "strip-ansi": "^6.0.0" } + }, + "wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", + "dev": true } } } diff --git a/benchmarks/package.json b/benchmarks/package.json index 36cec8a..902aa11 100644 --- a/benchmarks/package.json +++ b/benchmarks/package.json @@ -4,20 +4,22 @@ "description": "Benchmarks for @nrsk/sigma", "private": true, "scripts": { - "bench:all": "node dist/benchmarks/src/index.js", - "bench:json": "node dist/benchmarks/src/json/index.js", - "bench:tuple": "node dist/benchmarks/src/tuple/index.js", - "build": "tsc -p tsconfig.json", - "start": "npm run build && npm run bench:all" + "bench": "node dist/index.js", + "bench:many": "node dist/many/index.js", + "bench:json": "node dist/json/index.js", + "bench:tuple": "node dist/tuple/index.js", + "build": "rimraf dist && tsc -p tsconfig.json", + "start": "npm run build && npm run bench" }, "dependencies": { - "@nrsk/sigma": "2.0.0", + "@nrsk/sigma": "2.0.2", "benny": "^3.7.1", "parjs": "0.12.7" }, "devDependencies": { "@types/benchmark": "^2.1.1", - "@types/node": "^14.18.0", - "typescript": "^4.5.5" + "@types/node": "^14.18.18", + "rimraf": "^3.0.2", + "typescript": "^4.6.4" } } diff --git a/benchmarks/src/@helpers/index.ts b/benchmarks/src/@helpers/index.ts new file mode 100644 index 0000000..93ee959 --- /dev/null +++ b/benchmarks/src/@helpers/index.ts @@ -0,0 +1,22 @@ +import { complete, cycle } from 'benny' +import * as kleur from 'kleur' + +export const handlers = [ + cycle(), + + complete((summary) => { + const length = summary.results.length + + console.log() + console.log(kleur.blue(`Finished ${length} case${length !== 1 ? 's' : ''}!`)) + + if (length > 1) { + console.log(kleur.blue(' Fastest:'), summary.fastest.name) + console.log(kleur.blue(' Slowest:'), summary.slowest.name) + } + + console.log() + console.log('~~~') + console.log() + }) +] diff --git a/benchmarks/src/index.ts b/benchmarks/src/index.ts index a91e2c3..06bdbba 100644 --- a/benchmarks/src/index.ts +++ b/benchmarks/src/index.ts @@ -1,2 +1,3 @@ import './json' import './tuple' +import './many' diff --git a/benchmarks/src/json/index.ts b/benchmarks/src/json/index.ts index 6fdd37e..c8a74f5 100644 --- a/benchmarks/src/json/index.ts +++ b/benchmarks/src/json/index.ts @@ -1,20 +1,16 @@ -import { suite, add, cycle, complete } from 'benny' +import { suite, add } from 'benny' import { parse as parseSigma } from './sigma' import { parse as parseParjs } from './parjs' +import { handlers } from '../@helpers' import { SAMPLE } from './@sample' -const options = { - minSamples: 50 -} - suite( 'JSON :: sigma vs parjs', - add('sigma', () => parseSigma(SAMPLE), options), - add('parjs', () => parseParjs(SAMPLE), options), + add('sigma', () => parseSigma(SAMPLE)), + add('parjs', () => parseParjs(SAMPLE)), - cycle(), - complete() + ...handlers ) diff --git a/benchmarks/src/json/sigma.ts b/benchmarks/src/json/sigma.ts index 7c7f8a1..e07f300 100644 --- a/benchmarks/src/json/sigma.ts +++ b/benchmarks/src/json/sigma.ts @@ -1,4 +1,4 @@ -import { choice, sepBy, map, takeMid, optional, sequence } from '@nrsk/sigma/combinators' +import { choice, sepBy, optional, map, takeMid, sequence } from '@nrsk/sigma/combinators' import { defer, float, int, regexp, run, string, whitespace } from '@nrsk/sigma/parsers' import * as Ast from './ast' @@ -101,7 +101,7 @@ const Space = optional(whitespace()) const StringLiteral = regexp(/"([^"]|\\.)*"/g, 'string') // Utility. -const match = (match: string) => takeMid(Space, string(match), Space) +const match = (s: string) => takeMid(Space, string(s), Space) // Composites. const JsonRoot = defer() @@ -141,13 +141,9 @@ JsonArray.with( ) JsonNull.with(map(match(Keywords.Null), toNull)) - JsonString.with(map(StringLiteral, toString)) - JsonNumber.with(map(NumberLiteral, toNumber)) - JsonBoolean.with(map(choice(match(Keywords.True), match(Keywords.False)), toBoolean)) - JsonValue.with(choice(JsonObject, JsonArray, JsonString, JsonNumber, JsonBoolean, JsonNull)) /* Wrapper for bench runner. */ @@ -155,12 +151,12 @@ JsonValue.with(choice(JsonObject, JsonArray, JsonString, JsonNumber, JsonBoolean export function parse(text: string): Ast.JsonRoot { const result = run(JsonRoot).with(text) - switch (result.kind) { - case 'success': { + switch (result.isOk) { + case true: { return result.value } - case 'failure': { + case false: { return { type: 'object', values: [] diff --git a/benchmarks/src/many/@sample.ts b/benchmarks/src/many/@sample.ts new file mode 100644 index 0000000..ca9adc2 --- /dev/null +++ b/benchmarks/src/many/@sample.ts @@ -0,0 +1,12 @@ +export const SAMPLE = + `x!x!x!x!x!x!x!x!x!x!x!x!x!x!x!x!x!x!x!x!x!x!x!x!x!x!x!x!x!x!x!x!x!x!x!x!x!x!x!x!` + + `x!x!x!x!x!x!x!x!x!x!x!x!x!x!x!x!x!x!x!x!x!x!x!x!x!x!x!x!x!x!x!x!x!x!x!x!x!x!x!x!` + + `x!x!x!x!x!x!x!x!x!x!x!x!x!x!x!x!x!x!x!x!x!x!x!x!x!x!x!x!x!x!x!x!x!x!x!x!x!x!x!x!` + + `x!x!x!x!x!x!x!x!x!x!x!x!x!x!x!x!x!x!x!x!x!x!x!x!x!x!x!x!x!x!x!x!x!x!x!x!x!x!x!x!` + + `x!x!x!x!x!x!x!x!x!x!x!x!x!x!x!x!x!x!x!x!x!x!x!x!x!x!x!x!x!x!x!x!x!x!x!x!x!x!x!x!` + + `x!x!x!x!x!x!x!x!x!x!x!x!x!x!x!x!x!x!x!x!x!x!x!x!x!x!x!x!x!x!x!x!x!x!x!x!x!x!x!x!` + + `x!x!x!x!x!x!x!x!x!x!x!x!x!x!x!x!x!x!x!x!x!x!x!x!x!x!x!x!x!x!x!x!x!x!x!x!x!x!x!x!` + + `x!x!x!x!x!x!x!x!x!x!x!x!x!x!x!x!x!x!x!x!x!x!x!x!x!x!x!x!x!x!x!x!x!x!x!x!x!x!x!x!` + + `x!x!x!x!x!x!x!x!x!x!x!x!x!x!x!x!x!x!x!x!x!x!x!x!x!x!x!x!x!x!x!x!x!x!x!x!x!x!x!x!` + + `x!x!x!x!x!x!x!x!x!x!x!x!x!x!x!x!x!x!x!x!x!x!x!x!x!x!x!x!x!x!x!x!x!x!x!x!x!x!x!x!` + + `x!x!x!x!x!x!x!x!x!x!x!x!x!x!x!x!x!x!x!x!x!x!x!x!x!x!x!x!x!x!x!x!x!x!x!x!x!x!x!x!` diff --git a/benchmarks/src/many/index.ts b/benchmarks/src/many/index.ts new file mode 100644 index 0000000..827cdad --- /dev/null +++ b/benchmarks/src/many/index.ts @@ -0,0 +1,16 @@ +import { suite, add } from 'benny' + +import { parse as parseSigma } from './sigma' +import { parse as parseParjs } from './parjs' +import { handlers } from '../@helpers' + +import { SAMPLE } from './@sample' + +suite( + 'many :: sigma vs parjs', + + add('sigma', () => parseSigma(SAMPLE)), + add('parjs', () => parseParjs(SAMPLE)), + + ...handlers +) diff --git a/benchmarks/src/many/parjs.ts b/benchmarks/src/many/parjs.ts new file mode 100644 index 0000000..d07ec2a --- /dev/null +++ b/benchmarks/src/many/parjs.ts @@ -0,0 +1,16 @@ +import { many } from 'parjs/combinators' +import { string } from 'parjs' + +const Parser = string('x!').pipe(many()) + +/* Wrapper for bench runner. */ + +export function parse(text: string): Array { + const result = Parser.parse(text) + + if (result.kind === 'OK') { + return result.value + } + + return [] +} diff --git a/benchmarks/src/many/sigma.ts b/benchmarks/src/many/sigma.ts new file mode 100644 index 0000000..cc2b7fa --- /dev/null +++ b/benchmarks/src/many/sigma.ts @@ -0,0 +1,20 @@ +import { many } from '@nrsk/sigma/combinators' +import { run, string } from '@nrsk/sigma/parsers' + +const Parser = many(string('x!')) + +/* Wrapper for bench runner. */ + +export function parse(text: string): Array { + const result = run(Parser).with(text) + + switch (result.isOk) { + case true: { + return result.value + } + + case false: { + return [] + } + } +} diff --git a/benchmarks/src/tuple/index.ts b/benchmarks/src/tuple/index.ts index 3a98aff..cf0ebde 100644 --- a/benchmarks/src/tuple/index.ts +++ b/benchmarks/src/tuple/index.ts @@ -1,20 +1,16 @@ -import { suite, add, cycle, complete } from 'benny' +import { suite, add } from 'benny' import { parse as parseSigma } from './sigma' import { parse as parseParjs } from './parjs' +import { handlers } from '../@helpers' import { SAMPLE } from './@sample' -const options = { - minSamples: 50 -} - suite( 'Tuple :: sigma vs parjs', - add('sigma', () => parseSigma(SAMPLE), options), - add('parjs', () => parseParjs(SAMPLE), options), + add('sigma', () => parseSigma(SAMPLE)), + add('parjs', () => parseParjs(SAMPLE)), - cycle(), - complete() + ...handlers ) diff --git a/benchmarks/src/tuple/sigma.ts b/benchmarks/src/tuple/sigma.ts index 00adcb8..cc193e0 100644 --- a/benchmarks/src/tuple/sigma.ts +++ b/benchmarks/src/tuple/sigma.ts @@ -49,12 +49,12 @@ TupleList.with( export function parse(text: string): Ast.ListNode { const result = run(TupleList).with(text) - switch (result.kind) { - case 'success': { + switch (result.isOk) { + case true: { return result.value } - case 'failure': { + case false: { return { type: 'list', value: [] diff --git a/benchmarks/tsconfig.json b/benchmarks/tsconfig.json index 1ebecf5..f15d4b3 100644 --- a/benchmarks/tsconfig.json +++ b/benchmarks/tsconfig.json @@ -3,7 +3,7 @@ "compilerOptions": { "target": "es2021", "outDir": "./dist", - "incremental": true, + "sourceMap": false, "declaration": false }, "include": ["src"],