diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index debaac9da..ec6d6d706 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -9,7 +9,7 @@ jobs: strategy: matrix: os: [ubuntu-latest] - node-version: [18.x, 20.x, 22.x] + node-version: [20.x, 22.x, 24.x] steps: - uses: actions/checkout@v2 @@ -29,26 +29,3 @@ jobs: yarn build-types [ $(git diff types.d.ts | wc -l) -gt 0 ] && echo 'Diff exists in types.d.ts. Please change jsdoc.' && exit 1 tsc --noEmit types.d.ts - - - name: install valgrind - run: sudo apt-get install -y valgrind - - - name: benchmark - run: python cachegrind.py node test/benchmark2.js > output.txt - - - name: Download previous benchmark result - uses: actions/cache@v1 - with: - path: ./cache - key: ${{ runner.os }}-${{matrix.node-version}}-benchmark - - - name: Store benchmark result - uses: benchmark-action/github-action-benchmark@v1 - with: - tool: "customSmallerIsBetter" - output-file-path: output.txt - external-data-json-path: ./cache/benchmark-data.json - alert-threshold: "105%" - fail-on-alert: true - env: - CI: true diff --git a/cachegrind.py b/cachegrind.py deleted file mode 100644 index ce1c38024..000000000 --- a/cachegrind.py +++ /dev/null @@ -1,137 +0,0 @@ -""" -Proof-of-concept: run_with_cachegrind a program under Cachegrind, combining all the various -metrics into one single performance metric. - -Requires Python 3. - -License: https://opensource.org/licenses/MIT - -## Features - -* Disables ASLR. -* Sets consistent cache sizes. -* Calculates a combined performance metric. - -For more information see the detailed write up at: - -https://pythonspeed.com/articles/consistent-benchmarking-in-ci/ - -## Usage - -This script has no compatibility guarnatees, I recommend copying it into your -repository. To use: - -$ python3 cachegrind.py ./yourprogram --yourparam=yourvalues - -If you're benchmarking Python, make sure to set PYTHONHASHSEED to a fixed value -(e.g. `export PYTHONHASHSEED=1234`). Other languages may have similar -requirements to reduce variability. - -The last line printed will be a combined performance metric, but you can tweak -the script to extract more info, or use it as a library. - -Copyright © 2020, Hyphenated Enterprises LLC. -""" - -import json -from typing import List, Dict -from subprocess import check_call, check_output -import sys -from tempfile import NamedTemporaryFile - -ARCH = check_output(["uname", "-m"]).strip() - - -def run_with_cachegrind(args_list: List[str]) -> Dict[str, int]: - """ - Run the the given program and arguments under Cachegrind, parse the - Cachegrind specs. - - For now we just ignore program output, and in general this is not robust. - """ - temp_file = NamedTemporaryFile("r+") - check_call([ - # Disable ASLR: - "setarch", - ARCH, - "-R", - "valgrind", - "--tool=cachegrind", - # Set some reasonable L1 and LL values, based on Haswell. You can set - # your own, important part is that they are consistent across runs, - # instead of the default of copying from the current machine. - "--I1=32768,8,64", - "--D1=32768,8,64", - "--LL=8388608,16,64", - "--cachegrind-out-file=" + temp_file.name, - ] + args_list) - return parse_cachegrind_output(temp_file) - - -def parse_cachegrind_output(temp_file): - # Parse the output file: - lines = iter(temp_file) - for line in lines: - if line.startswith("events: "): - header = line[len("events: "):].strip() - break - for line in lines: - last_line = line - assert last_line.startswith("summary: ") - last_line = last_line[len("summary:"):].strip() - return dict(zip(header.split(), [int(i) for i in last_line.split()])) - - -def get_counts(cg_results: Dict[str, int]) -> Dict[str, int]: - """ - Given the result of run_with_cachegrind(), figure out the parameters we will use for final - estimate. - - We pretend there's no L2 since Cachegrind doesn't currently support it. - - Caveats: we're not including time to process instructions, only time to - access instruction cache(s), so we're assuming time to fetch and run_with_cachegrind - instruction is the same as time to retrieve data if they're both to L1 - cache. - """ - result = {} - d = cg_results - - ram_hits = d["DLmr"] + d["DLmw"] + d["ILmr"] - - l3_hits = d["I1mr"] + d["D1mw"] + d["D1mr"] - ram_hits - - total_memory_rw = d["Ir"] + d["Dr"] + d["Dw"] - l1_hits = total_memory_rw - l3_hits - ram_hits - assert total_memory_rw == l1_hits + l3_hits + ram_hits - - result["l1"] = l1_hits - result["l3"] = l3_hits - result["ram"] = ram_hits - - return result - - -def combined_instruction_estimate(counts: Dict[str, int]) -> int: - """ - Given the result of run_with_cachegrind(), return estimate of total time to run_with_cachegrind. - - Multipliers were determined empirically, but some research suggests they're - a reasonable approximation for cache time ratios. L3 is probably too low, - but then we're not simulating L2... - """ - return counts["l1"] + (5 * counts["l3"]) + (35 * counts["ram"]) - - -def github_action_benchmark_json(value): - return json.dumps([ - { - "name": "score", - "unit": "", - "value": value, - } - ]) - - -if __name__ == "__main__": - print(github_action_benchmark_json(combined_instruction_estimate(get_counts(run_with_cachegrind(sys.argv[1:]))))) diff --git a/package.json b/package.json index d2ac370e6..987667c76 100644 --- a/package.json +++ b/package.json @@ -57,30 +57,29 @@ ], "license": "BSD-3-Clause", "devDependencies": { - "@babel/core": "^7.26.0", - "@babel/preset-env": "^7.26.0", - "@eslint/eslintrc": "^3.1.0", - "@eslint/js": "^9.14.0", - "@types/node": "^22.9.0", - "babel-loader": "^9.2.1", + "@babel/core": "^7.27.4", + "@babel/preset-env": "^7.27.2", + "@eslint/js": "^9.29.0", + "@types/node": "^24.0.4", + "babel-loader": "^10.0.0", "benchmark": "^2.1.4", "coveralls": "^3.0.3", - "eslint": "^9.14.0", - "eslint-config-prettier": "^9.1.0", - "eslint-plugin-jest": "^28.9.0", - "eslint-plugin-prettier": "^5.2.1", - "globals": "^15.12.0", - "husky": "^9.1.6", - "jest": "^29.7.0", + "eslint": "^9.29.0", + "eslint-config-prettier": "^10.1.5", + "eslint-plugin-jest": "^29.0.1", + "eslint-plugin-prettier": "^5.5.0", + "globals": "^16.2.0", + "husky": "^9.1.7", + "jest": "^30.0.3", "jest-runner-eslint": "^2.2.1", - "jsdoc": "^3.6.11", + "jsdoc": "^4.0.4", "jsdoc-template": "^1.2.0", "lodash.template": ">=4.5.0", - "prettier": "^3.3.3", + "prettier": "^3.6.1", "tsd-jsdoc": "^2.5.0", - "typescript": "^5.6.3", + "typescript": "^5.8.3", "webpack": "5.96.0", - "webpack-cli": "^5.1.4", + "webpack-cli": "^6.0.1", "yarpm": "^1.2.0" }, "dependencies": {} diff --git a/test/benchmark2.js b/test/benchmark2.js deleted file mode 100644 index d03e6cee7..000000000 --- a/test/benchmark2.js +++ /dev/null @@ -1,18 +0,0 @@ -const parser = require("./main"); - -const code = ` -