mirror of
https://github.com/oxc-project/oxc.git
synced 2026-11-04 10:29:58 +00:00
test(lexer): update just recipes to cover Neon implementation (#27705)
#27642 added an aarch64 Neon implementation of `classify`. So now we have 3 implementations. Update `just ready-lexer` recipe to test and lint all 3.
This commit is contained in:
1 parent
6a9a8f5e15
commit
a76e5fd80d
7 files changed
+89
-58
No files matched your search
@@ -1,5 +1,5 @@
|
|||||||
# Extra rustflags for building `oxc_lexer`'s SIMD core. Passed via `cargo --config` by the
|
# Extra rustflags for building `oxc_lexer`'s AVX2 implementation. Passed via `cargo --config` by the
|
||||||
# `just test-lexer-simd` / `just conformance-lexer-simd` recipes - see the justfile.
|
# `just *-lexer-avx2` recipes - see the justfile.
|
||||||
#
|
#
|
||||||
# `avx2`, `bmi2` and `popcnt` are not in the x86_64 baseline on any platform, so they have to be asked for explicitly,
|
# `avx2`, `bmi2` and `popcnt` are not in the x86_64 baseline on any platform, so they have to be asked for explicitly,
|
||||||
# even on an x86_64 host. Cargo joins `rustflags` arrays across config sources, so the per-target flags
|
# even on an x86_64 host. Cargo joins `rustflags` arrays across config sources, so the per-target flags
|
||||||
@@ -678,7 +678,7 @@ jobs:
|
|||||||
- variant: generic
|
- variant: generic
|
||||||
suffix: ""
|
suffix: ""
|
||||||
- variant: AVX2
|
- variant: AVX2
|
||||||
suffix: "-simd"
|
suffix: "-avx2"
|
||||||
steps:
|
steps:
|
||||||
- uses: taiki-e/checkout-action@7d1e50e93dc4fb3bba58f85018fadf77898aee8b # v1.4.2
|
- uses: taiki-e/checkout-action@7d1e50e93dc4fb3bba58f85018fadf77898aee8b # v1.4.2
|
||||||
|
|
||||||
@@ -687,7 +687,7 @@ jobs:
|
|||||||
uses: $/.github/actions/check-changes
|
uses: $/.github/actions/check-changes
|
||||||
with:
|
with:
|
||||||
packages: oxc_lexer,oxc_coverage
|
packages: oxc_lexer,oxc_coverage
|
||||||
paths: crates/oxc_lexer/,tasks/coverage/,.cargo/lexer-simd.toml,justfile,.github/workflows/ci.yml
|
paths: crates/oxc_lexer/,tasks/coverage/,.cargo/lexer-avx2.toml,justfile,.github/workflows/ci.yml
|
||||||
token: ${{ secrets.GITHUB_TOKEN }}
|
token: ${{ secrets.GITHUB_TOKEN }}
|
||||||
pr-number: ${{ github.event.pull_request.number }}
|
pr-number: ${{ github.event.pull_request.number }}
|
||||||
|
|
||||||
@@ -716,12 +716,12 @@ jobs:
|
|||||||
- name: Lint
|
- name: Lint
|
||||||
# No need to run on generic - already covered by "Lint" job
|
# No need to run on generic - already covered by "Lint" job
|
||||||
if: ${{ steps.filter.outputs.changed == 'true' && matrix.variant == 'AVX2' }}
|
if: ${{ steps.filter.outputs.changed == 'true' && matrix.variant == 'AVX2' }}
|
||||||
run: just lint-lexer-simd
|
run: just lint-lexer-avx2
|
||||||
|
|
||||||
- name: Test
|
- name: Test
|
||||||
# No need to run on generic - already covered by "Test Linux" job
|
# No need to run on generic - already covered by "Test Linux" job
|
||||||
if: ${{ steps.filter.outputs.changed == 'true' && matrix.variant == 'AVX2' }}
|
if: ${{ steps.filter.outputs.changed == 'true' && matrix.variant == 'AVX2' }}
|
||||||
run: just test-lexer-simd
|
run: just test-lexer-avx2
|
||||||
|
|
||||||
- wait: lexer-fixtures
|
- wait: lexer-fixtures
|
||||||
|
|
||||||
@@ -756,7 +756,7 @@ jobs:
|
|||||||
id: filter
|
id: filter
|
||||||
uses: $/.github/actions/check-changes
|
uses: $/.github/actions/check-changes
|
||||||
with:
|
with:
|
||||||
paths: crates/oxc_lexer/,tasks/benchmark/benches/lexer_wallclock_old.rs,tasks/benchmark/benches/lexer_wallclock_new.rs,tasks/benchmark/benches/lexer_common.rs,.cargo/lexer-simd.toml,justfile,.github/workflows/ci.yml
|
paths: crates/oxc_lexer/,tasks/benchmark/benches/lexer_wallclock_old.rs,tasks/benchmark/benches/lexer_wallclock_new.rs,tasks/benchmark/benches/lexer_common.rs,.cargo/lexer-avx2.toml,justfile,.github/workflows/ci.yml
|
||||||
token: ${{ secrets.GITHUB_TOKEN }}
|
token: ${{ secrets.GITHUB_TOKEN }}
|
||||||
pr-number: ${{ github.event.pull_request.number }}
|
pr-number: ${{ github.event.pull_request.number }}
|
||||||
|
|
||||||
@@ -782,7 +782,7 @@ jobs:
|
|||||||
CRITERION_HOME: ${{ runner.temp }}/criterion
|
CRITERION_HOME: ${{ runner.temp }}/criterion
|
||||||
run: |
|
run: |
|
||||||
set -o pipefail
|
set -o pipefail
|
||||||
just bench-lexer-simd | tee "$RUNNER_TEMP/bench.log"
|
just bench-lexer-avx2 | tee "$RUNNER_TEMP/bench.log"
|
||||||
grep -qxF "Lexer implementation: AVX2" "$RUNNER_TEMP/bench.log" ||
|
grep -qxF "Lexer implementation: AVX2" "$RUNNER_TEMP/bench.log" ||
|
||||||
{ echo "::error::Expected AVX2, but the benchmark reported otherwise"; exit 1; }
|
{ echo "::error::Expected AVX2, but the benchmark reported otherwise"; exit 1; }
|
||||||
|
|
||||||
|
|||||||
+1
-1
@@ -170,7 +170,7 @@ oxc_formatter_tests = { path = "crates/oxc_formatter_tests" } # Formatter test i
|
|||||||
oxc_formatter_toml = { path = "crates/oxc_formatter_toml" } # TOML formatter
|
oxc_formatter_toml = { path = "crates/oxc_formatter_toml" } # TOML formatter
|
||||||
oxc_formatter_yaml = { path = "crates/oxc_formatter_yaml" } # YAML formatter
|
oxc_formatter_yaml = { path = "crates/oxc_formatter_yaml" } # YAML formatter
|
||||||
oxc_language_server = { path = "crates/oxc_language_server", default-features = false } # Language server
|
oxc_language_server = { path = "crates/oxc_language_server", default-features = false } # Language server
|
||||||
oxc_lexer = { path = "crates/oxc_lexer" } # JS/TS lexer (incubating; x86_64 SIMD core, scalar fallback)
|
oxc_lexer = { path = "crates/oxc_lexer" } # JS/TS lexer (incubating; AVX2, Neon, and generic implementations)
|
||||||
oxc_linter = { path = "crates/oxc_linter" } # Linting engine
|
oxc_linter = { path = "crates/oxc_linter" } # Linting engine
|
||||||
oxc_macros = { path = "crates/oxc_macros" } # Proc macros
|
oxc_macros = { path = "crates/oxc_macros" } # Proc macros
|
||||||
oxc_tasks_common = { path = "tasks/common" } # Task utilities
|
oxc_tasks_common = { path = "tasks/common" } # Task utilities
|
||||||
|
|||||||
@@ -149,44 +149,63 @@ ast:
|
|||||||
|
|
||||||
# ==================== LEXER ====================
|
# ==================== LEXER ====================
|
||||||
|
|
||||||
# `oxc_lexer` compiles to one of two implementations, chosen at build time:
|
# `oxc_lexer` compiles to one of 3 implementations, chosen at build time:
|
||||||
#
|
#
|
||||||
# * SIMD core, on x86_64 with `avx2` + `bmi2` + `popcnt` enabled
|
# * AVX2, on x86_64 with `avx2` + `bmi2` + `popcnt` enabled
|
||||||
# * Scalar fallback, everywhere else
|
# * Neon, on aarch64 (every aarch64 target with `std` enables `neon`)
|
||||||
|
# * Generic, everywhere else
|
||||||
#
|
#
|
||||||
# Both need testing, and they should produce identical results. None of `avx2`, `bmi2` and `popcnt` is in the x86_64
|
# Parts of the pipeline which have no AVX2 or Neon implementation use the generic one.
|
||||||
# baseline on any platform, so reaching the SIMD core always means asking for them explicitly - even on an x86_64 host.
|
# All 3 need testing, and they should produce identical results.
|
||||||
# The flags live in `.cargo/lexer-simd.toml`, passed with `cargo --config`, which avoids shell quoting entirely
|
#
|
||||||
|
# Each task has 3 recipes:
|
||||||
|
#
|
||||||
|
# * `*-lexer` builds for the host - Neon on an ARM host, generic on an x86_64 host.
|
||||||
|
# * `*-lexer-avx2` builds the AVX2 implementation for x86_64.
|
||||||
|
# * `*-lexer-generic` builds the generic implementation for x86_64.
|
||||||
|
# On an x86_64 host, that's the same as `*-lexer`.
|
||||||
|
#
|
||||||
|
# None of `avx2`, `bmi2` and `popcnt` is in the x86_64 baseline on any platform, so reaching the AVX2 implementation
|
||||||
|
# always means asking for them explicitly - even on an x86_64 host.
|
||||||
|
# The flags live in `.cargo/lexer-avx2.toml`, passed with `cargo --config`, which avoids shell quoting entirely
|
||||||
# (this justfile runs PowerShell on Windows).
|
# (this justfile runs PowerShell on Windows).
|
||||||
#
|
#
|
||||||
# `--target` is always passed, so that the flags land on the triple the config file names,
|
# `--target` is always passed for the x86_64 builds, so that the flags land on the triple the config file names.
|
||||||
# and so that the two builds get separate target dirs instead of invalidating each other.
|
|
||||||
#
|
#
|
||||||
# On an ARM host the SIMD build is cross-compiled and run under emulation - macOS provides that via Rosetta 2.
|
# On an ARM host the x86_64 builds are cross-compiled and run under emulation - macOS provides that via Rosetta 2.
|
||||||
# On Mac, ensure x86_64 target is installed: `rustup target add x86_64-apple-darwin`.
|
# On Mac, ensure x86_64 target is installed: `rustup target add x86_64-apple-darwin`.
|
||||||
# If it's not, you'll get a "can't find crate for std" error.
|
# If it's not, you'll get a "can't find crate for std" error.
|
||||||
#
|
#
|
||||||
# On ARM Linux or ARM Windows it will fail, loudly, when linking or running.
|
# On ARM Linux or ARM Windows they will fail, loudly, when linking or running.
|
||||||
_lexer-simd-target := if os() == "macos" { "x86_64-apple-darwin" } else if os() == "windows" { "x86_64-pc-windows-msvc" } else { "x86_64-unknown-linux-gnu" }
|
_lexer-x86-target := if os() == "macos" { "x86_64-apple-darwin" } else if os() == "windows" { "x86_64-pc-windows-msvc" } else { "x86_64-unknown-linux-gnu" }
|
||||||
_lexer-simd := "--target " + _lexer-simd-target + " --config .cargo/lexer-simd.toml"
|
_lexer-generic := "--target " + _lexer-x86-target
|
||||||
|
_lexer-avx2 := _lexer-generic + " --config .cargo/lexer-avx2.toml"
|
||||||
|
|
||||||
# Run `oxc_lexer`'s tests against the scalar fallback
|
# Run `oxc_lexer`'s tests, built for the host
|
||||||
test-lexer *args='':
|
test-lexer *args='':
|
||||||
cargo test -p oxc_lexer {{args}}
|
cargo test -p oxc_lexer {{args}}
|
||||||
|
|
||||||
# Run `oxc_lexer`'s tests against the SIMD core
|
# Run `oxc_lexer`'s tests against the AVX2 implementation
|
||||||
test-lexer-simd *args='':
|
test-lexer-avx2 *args='':
|
||||||
cargo test -p oxc_lexer {{_lexer-simd}} {{args}}
|
cargo test -p oxc_lexer {{_lexer-avx2}} {{args}}
|
||||||
|
|
||||||
# Run lexer conformance against the scalar fallback
|
# Run `oxc_lexer`'s tests against the generic implementation, on x86_64
|
||||||
|
test-lexer-generic *args='':
|
||||||
|
cargo test -p oxc_lexer {{_lexer-generic}} {{args}}
|
||||||
|
|
||||||
|
# Run lexer conformance, built for the host
|
||||||
conformance-lexer *args='':
|
conformance-lexer *args='':
|
||||||
cargo run -p oxc_coverage --profile coverage --features lexer -- lexer {{args}}
|
cargo run -p oxc_coverage --profile coverage --features lexer -- lexer {{args}}
|
||||||
|
|
||||||
# Run lexer conformance against the SIMD core
|
# Run lexer conformance against the AVX2 implementation
|
||||||
conformance-lexer-simd *args='':
|
conformance-lexer-avx2 *args='':
|
||||||
cargo run -p oxc_coverage --profile coverage {{_lexer-simd}} --features lexer -- lexer {{args}}
|
cargo run -p oxc_coverage --profile coverage {{_lexer-avx2}} --features lexer -- lexer {{args}}
|
||||||
|
|
||||||
# Lint `oxc_lexer` and the conformance harness against the scalar fallback
|
# Run lexer conformance against the generic implementation, on x86_64
|
||||||
|
conformance-lexer-generic *args='':
|
||||||
|
cargo run -p oxc_coverage --profile coverage {{_lexer-generic}} --features lexer -- lexer {{args}}
|
||||||
|
|
||||||
|
# Lint `oxc_lexer` and the conformance harness, built for the host
|
||||||
[unix]
|
[unix]
|
||||||
lint-lexer *args='':
|
lint-lexer *args='':
|
||||||
CARGO_BUILD_WARNINGS=deny cargo clippy -p oxc_lexer -p oxc_coverage --all-targets --all-features {{args}}
|
CARGO_BUILD_WARNINGS=deny cargo clippy -p oxc_lexer -p oxc_coverage --all-targets --all-features {{args}}
|
||||||
@@ -195,13 +214,17 @@ lint-lexer *args='':
|
|||||||
lint-lexer *args='':
|
lint-lexer *args='':
|
||||||
$Env:CARGO_BUILD_WARNINGS='deny'; cargo clippy -p oxc_lexer -p oxc_coverage --all-targets --all-features {{args}}
|
$Env:CARGO_BUILD_WARNINGS='deny'; cargo clippy -p oxc_lexer -p oxc_coverage --all-targets --all-features {{args}}
|
||||||
|
|
||||||
# Lint `oxc_lexer` and the conformance harness against the SIMD core
|
# Lint `oxc_lexer` and the conformance harness against the AVX2 implementation
|
||||||
lint-lexer-simd *args='':
|
lint-lexer-avx2 *args='':
|
||||||
just lint-lexer {{_lexer-simd}} {{args}}
|
just lint-lexer {{_lexer-avx2}} {{args}}
|
||||||
|
|
||||||
|
# Lint `oxc_lexer` and the conformance harness against the generic implementation, on x86_64
|
||||||
|
lint-lexer-generic *args='':
|
||||||
|
just lint-lexer {{_lexer-generic}} {{args}}
|
||||||
|
|
||||||
# The lexer benchmarks measure wallclock time. Unlike the other benchmarks, they don't run on CodSpeed.
|
# The lexer benchmarks measure wallclock time. Unlike the other benchmarks, they don't run on CodSpeed.
|
||||||
#
|
#
|
||||||
# `oxc_parser`'s lexer is always built without the SIMD flags, so it's benchmarked in a separate build
|
# `oxc_parser`'s lexer is always built without the AVX2 flags, so it's benchmarked in a separate build
|
||||||
# from `oxc_lexer`. Its results are saved as criterion baseline `lexer_old`, and then `oxc_lexer`
|
# from `oxc_lexer`. Its results are saved as criterion baseline `lexer_old`, and then `oxc_lexer`
|
||||||
# is compared against that baseline.
|
# is compared against that baseline.
|
||||||
# The "change" which criterion reports for `oxc_lexer` is its time relative to `oxc_parser`'s.
|
# The "change" which criterion reports for `oxc_lexer` is its time relative to `oxc_parser`'s.
|
||||||
@@ -213,37 +236,44 @@ lint-lexer-simd *args='':
|
|||||||
# `args` are passed to criterion, e.g. `just bench-lexer App.tsx` to run only that file.
|
# `args` are passed to criterion, e.g. `just bench-lexer App.tsx` to run only that file.
|
||||||
# The recipes set the baseline options themselves, so don't pass those.
|
# The recipes set the baseline options themselves, so don't pass those.
|
||||||
#
|
#
|
||||||
# On an ARM host, `bench-lexer-simd` compares `oxc_parser` running natively against `oxc_lexer`
|
# On an ARM host, `bench-lexer-avx2` compares `oxc_parser` running natively against `oxc_lexer`
|
||||||
# running under emulation, so the comparison is meaningless.
|
# running under emulation, so the comparison is meaningless.
|
||||||
_bench-lexer := "cargo bench -p oxc_benchmark --no-default-features --features lexer_wallclock --bench"
|
_bench-lexer := "cargo bench -p oxc_benchmark --no-default-features --features lexer_wallclock --bench"
|
||||||
|
|
||||||
# Benchmark `oxc_lexer`'s scalar fallback against `oxc_parser`'s lexer
|
# Benchmark `oxc_lexer`, built for the host, against `oxc_parser`'s lexer
|
||||||
bench-lexer *args='':
|
bench-lexer *args='':
|
||||||
{{_bench-lexer}} lexer_wallclock_old --bench lexer_wallclock_new --no-run
|
{{_bench-lexer}} lexer_wallclock_old --bench lexer_wallclock_new --no-run
|
||||||
{{_bench-lexer}} lexer_wallclock_old -- --save-baseline lexer_old {{args}}
|
{{_bench-lexer}} lexer_wallclock_old -- --save-baseline lexer_old {{args}}
|
||||||
{{_bench-lexer}} lexer_wallclock_new -- --baseline lexer_old {{args}}
|
{{_bench-lexer}} lexer_wallclock_new -- --baseline lexer_old {{args}}
|
||||||
|
|
||||||
# Benchmark `oxc_lexer`'s SIMD core against `oxc_parser`'s lexer
|
# Benchmark `oxc_lexer`'s AVX2 implementation against `oxc_parser`'s lexer
|
||||||
bench-lexer-simd *args='':
|
bench-lexer-avx2 *args='':
|
||||||
{{_bench-lexer}} lexer_wallclock_old --no-run
|
{{_bench-lexer}} lexer_wallclock_old --no-run
|
||||||
{{_bench-lexer}} lexer_wallclock_new {{_lexer-simd}} --no-run
|
{{_bench-lexer}} lexer_wallclock_new {{_lexer-avx2}} --no-run
|
||||||
{{_bench-lexer}} lexer_wallclock_old -- --save-baseline lexer_old {{args}}
|
{{_bench-lexer}} lexer_wallclock_old -- --save-baseline lexer_old {{args}}
|
||||||
{{_bench-lexer}} lexer_wallclock_new {{_lexer-simd}} -- --baseline lexer_old {{args}}
|
{{_bench-lexer}} lexer_wallclock_new {{_lexer-avx2}} -- --baseline lexer_old {{args}}
|
||||||
|
|
||||||
# `ready-lexer` fails if any step fails, or if conformance changes the lexer snapshots.
|
# `ready-lexer` fails if any step fails, or if conformance changes the lexer snapshots.
|
||||||
# Only the lexer snapshots are checked for changes, so it can be run with other uncommitted changes.
|
# Only the lexer snapshots are checked for changes, so it can be run with other uncommitted changes.
|
||||||
# Snapshots are checked after each conformance run, because the SIMD run overwrites the snapshots from the scalar run.
|
# Snapshots are checked after each conformance run, because each run overwrites the snapshots from the one before.
|
||||||
|
#
|
||||||
|
# The generic implementation on x86_64 is only run on hosts which aren't x86_64.
|
||||||
|
# On an x86_64 host, it's the same as the host build, which `ready-lexer` runs anyway.
|
||||||
_lexer-snapshots := "tasks/coverage/snapshots/lexer_*"
|
_lexer-snapshots := "tasks/coverage/snapshots/lexer_*"
|
||||||
|
|
||||||
# Lint, test, and run conformance for `oxc_lexer` against both implementations, and check snapshots are unchanged
|
# Lint, test, and run conformance for `oxc_lexer` against each implementation, and check snapshots are unchanged
|
||||||
ready-lexer:
|
ready-lexer:
|
||||||
just lint-lexer
|
just lint-lexer
|
||||||
just lint-lexer-simd
|
just lint-lexer-avx2
|
||||||
|
{{ if arch() == "x86_64" { "" } else { "just lint-lexer-generic" } }}
|
||||||
just test-lexer
|
just test-lexer
|
||||||
just test-lexer-simd
|
just test-lexer-avx2
|
||||||
|
{{ if arch() == "x86_64" { "" } else { "just test-lexer-generic" } }}
|
||||||
just conformance-lexer
|
just conformance-lexer
|
||||||
git diff --exit-code HEAD -- '{{_lexer-snapshots}}'
|
git diff --exit-code HEAD -- '{{_lexer-snapshots}}'
|
||||||
just conformance-lexer-simd
|
just conformance-lexer-avx2
|
||||||
|
git diff --exit-code HEAD -- '{{_lexer-snapshots}}'
|
||||||
|
{{ if arch() == "x86_64" { "" } else { "just conformance-lexer-generic" } }}
|
||||||
git diff --exit-code HEAD -- '{{_lexer-snapshots}}'
|
git diff --exit-code HEAD -- '{{_lexer-snapshots}}'
|
||||||
just doc -p oxc_lexer
|
just doc -p oxc_lexer
|
||||||
|
|
||||||
|
|||||||
@@ -19,12 +19,12 @@ This benchmark does not run on CodSpeed, because its CPU simulation does not mod
|
|||||||
execution and branch prediction which `oxc_lexer` is designed to exploit.
|
execution and branch prediction which `oxc_lexer` is designed to exploit.
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
just bench-lexer # Scalar fallback
|
just bench-lexer # Built for the host (Neon on ARM, generic on x86_64)
|
||||||
just bench-lexer-simd # SIMD core (x86_64 only - on ARM Mac, it runs under emulation)
|
just bench-lexer-avx2 # AVX2 (x86_64 only - on ARM Mac, it runs under emulation)
|
||||||
```
|
```
|
||||||
|
|
||||||
`oxc_parser` is always built without the SIMD flags, so the 2 lexers are benchmarked in separate builds.
|
`oxc_parser` is always built without the AVX2 flags, so the 2 lexers are benchmarked in separate builds.
|
||||||
The "change" which criterion reports for `oxc_lexer` is its time relative to `oxc_parser`'s.
|
The "change" which criterion reports for `oxc_lexer` is its time relative to `oxc_parser`'s.
|
||||||
The "change" reported for `oxc_parser` (if any) is relative to its previous run.
|
The "change" reported for `oxc_parser` (if any) is relative to its previous run.
|
||||||
|
|
||||||
CI runs `just bench-lexer-simd` when `oxc_lexer` changes, and prints the results in the job log.
|
CI runs `just bench-lexer-avx2` when `oxc_lexer` changes, and prints the results in the job log.
|
||||||
@@ -3,12 +3,12 @@
|
|||||||
//! Not run on CodSpeed. `oxc_lexer` is designed to exploit out-of-order execution and branch prediction,
|
//! Not run on CodSpeed. `oxc_lexer` is designed to exploit out-of-order execution and branch prediction,
|
||||||
//! which CodSpeed's CPU simulation does not model. So these benchmarks measure wallclock time instead.
|
//! which CodSpeed's CPU simulation does not model. So these benchmarks measure wallclock time instead.
|
||||||
//!
|
//!
|
||||||
//! `oxc_lexer` compiles to its SIMD core or its scalar fallback depending on target features,
|
//! `oxc_lexer` compiles to its AVX2, Neon or generic implementation depending on target features,
|
||||||
//! which apply to the whole build. So the 2 lexers are benchmarked in separate builds:
|
//! which apply to the whole build. So the 2 lexers are benchmarked in separate builds:
|
||||||
//!
|
//!
|
||||||
//! 1. `lexer_wallclock_old` benchmarks `oxc_parser`'s lexer, built without the SIMD target features,
|
//! 1. `lexer_wallclock_old` benchmarks `oxc_parser`'s lexer, built without the AVX2 target features,
|
||||||
//! and saves the results as criterion baseline `lexer_old`.
|
//! and saves the results as criterion baseline `lexer_old`.
|
||||||
//! 2. This benchmark benchmarks `oxc_lexer` (either implementation), and compares it against that baseline.
|
//! 2. This benchmark benchmarks `oxc_lexer` (any implementation), and compares it against that baseline.
|
||||||
//! The "change" which criterion reports is `oxc_lexer`'s time relative to `oxc_parser`'s.
|
//! The "change" which criterion reports is `oxc_lexer`'s time relative to `oxc_parser`'s.
|
||||||
//!
|
//!
|
||||||
//! When saving the baseline, criterion also compares `oxc_parser` against its previous run, if there is one.
|
//! When saving the baseline, criterion also compares `oxc_parser` against its previous run, if there is one.
|
||||||
@@ -17,8 +17,8 @@
|
|||||||
//! Both lexers lex the same cleaned source text, so the contest is fair.
|
//! Both lexers lex the same cleaned source text, so the contest is fair.
|
||||||
//! See `cleaned_test_files` for why the source text needs cleaning.
|
//! See `cleaned_test_files` for why the source text needs cleaning.
|
||||||
//!
|
//!
|
||||||
//! Run with `just bench-lexer` (scalar fallback) or `just bench-lexer-simd` (SIMD core).
|
//! Run with `just bench-lexer` (built for the host) or `just bench-lexer-avx2` (AVX2 implementation).
|
||||||
//! CI runs `just bench-lexer-simd` when `oxc_lexer` changes, and prints the results in the job log.
|
//! CI runs `just bench-lexer-avx2` when `oxc_lexer` changes, and prints the results in the job log.
|
||||||
|
|
||||||
mod lexer_common;
|
mod lexer_common;
|
||||||
|
|
||||||
|
|||||||
@@ -46,11 +46,12 @@ walkdir = { workspace = true }
|
|||||||
|
|
||||||
[features]
|
[features]
|
||||||
# Differential lexer conformance, opt-in because it is slow and `oxc_lexer` is still incubating.
|
# Differential lexer conformance, opt-in because it is slow and `oxc_lexer` is still incubating.
|
||||||
# The harness runs against whichever of the lexer's two implementations the build selects:
|
# The harness runs against whichever of the lexer's implementations the build selects:
|
||||||
#
|
#
|
||||||
# * SIMD core (x86_64 only): RUSTFLAGS="-C target-feature=+avx2,+bmi2,+popcnt" cargo coverage --features lexer -- lexer
|
# * AVX2 (x86_64 only): RUSTFLAGS="-C target-feature=+avx2,+bmi2,+popcnt" cargo coverage --features lexer -- lexer
|
||||||
# * Scalar fallback: cargo coverage --features lexer -- lexer
|
# * Neon (aarch64) or generic (everywhere else): cargo coverage --features lexer -- lexer
|
||||||
#
|
#
|
||||||
# `avx2`/`bmi2`/`popcnt` are not in the x86_64 baseline on any platform, so the rustflags are required
|
# `avx2`/`bmi2`/`popcnt` are not in the x86_64 baseline on any platform, so the rustflags are required
|
||||||
# to reach the SIMD core even on an x86_64 host.
|
# to reach the AVX2 implementation even on an x86_64 host.
|
||||||
|
# The `just *-lexer*` recipes run conformance for each implementation - see the justfile.
|
||||||
lexer = ["dep:oxc_lexer", "oxc_lexer/oxc_diagnostics"]
|
lexer = ["dep:oxc_lexer", "oxc_lexer/oxc_diagnostics"]
|
||||||
Reference in new issue
Block a user