mirror of
https://github.com/oxc-project/oxc.git
synced 2026-11-04 10:29:58 +00:00
perf(minifier): evaluate ternary branches once in minimize_conditional_expression (#23479)
## What & why `minimize_conditional_expression` ran two folds — the boolean fold (`a ? true : false` → `!!a`) and the number fold (`a ? 1 : 0` → `+a`) — and **each** independently called `expr.consequent.evaluate_value(ctx)` and `expr.alternate.evaluate_value(ctx)`. So every ternary evaluated each branch **twice** (4 `evaluate_value` calls per `ConditionalExpression`). `evaluate_value` is a recursive constant-evaluation walk over the operand subtree. This hoists the two results and reuses them across both folds (4 → 2 calls per ternary). `minimize_conditional_expression` runs in `exit_expression` on every `ConditionalExpression`, across the fixed-point peephole loop, and ternaries are common — so this is a hot path. ```rust let consequent_value = expr.consequent.evaluate_value(ctx); let alternate_value = expr.alternate.evaluate_value(ctx); // boolean fold reads the cached values clone-free (as_ref + variant match == into_boolean) // number fold consumes them (into_number) — last use ``` The boolean fold reads the cached values **clone-free** (an `as_ref()` + `Boolean` variant match, identical to `into_boolean`); the number fold consumes them. Nothing mutates the operands between the two folds (the boolean fold only mutates inside arms that `return`), so the cached values are valid. ## Allocations (measured) `cargo allocs` shows a small system-allocation reduction, no regressions: | file | sys allocs: before → after | | --- | --- | | checker.ts | 166 → 162 (**−4**) | | pdf.mjs | 2614 → 2613 (**−1**) | (Arena allocs unchanged.) The primary effect is the halved `evaluate_value` work (instruction count) — CodSpeed will arbitrate that on this PR. The change is structured to never do more work than before. ## Behavior-preserving `cargo test -p oxc_minifier` (535 tests) passes; no snapshot drift beyond the allocation snapshot above. --- Prepared with AI assistance. --------- Co-authored-by: Cameron Clark <cameron.clark@hey.com>
This commit is contained in:
1 parent
e409fe0ee0
commit
d1fa6e09af
2 files changed
+19
-12
No files matched your search
@@ -377,16 +377,25 @@ impl<'a> PeepholeOptimizations {
|
||||
}
|
||||
}
|
||||
|
||||
let consequent_value = expr.consequent.evaluate_value(ctx);
|
||||
let alternate_value = expr.alternate.evaluate_value(ctx);
|
||||
|
||||
// "a ? true : false" => "!!a"
|
||||
// "a ? false : true" => "!a"
|
||||
match (
|
||||
expr.consequent
|
||||
.evaluate_value(ctx)
|
||||
.and_then(ConstantValue::into_boolean)
|
||||
consequent_value
|
||||
.as_ref()
|
||||
.and_then(|v| match v {
|
||||
ConstantValue::Boolean(b) => Some(*b),
|
||||
_ => None,
|
||||
})
|
||||
.filter(|_| !expr.consequent.may_have_side_effects(ctx)),
|
||||
expr.alternate
|
||||
.evaluate_value(ctx)
|
||||
.and_then(ConstantValue::into_boolean)
|
||||
alternate_value
|
||||
.as_ref()
|
||||
.and_then(|v| match v {
|
||||
ConstantValue::Boolean(b) => Some(*b),
|
||||
_ => None,
|
||||
})
|
||||
.filter(|_| !expr.alternate.may_have_side_effects(ctx)),
|
||||
) {
|
||||
(Some(true), Some(false)) => {
|
||||
@@ -406,12 +415,10 @@ impl<'a> PeepholeOptimizations {
|
||||
// "a ? 1 : 0" => "+a" (if a is boolean) or "+!!a" (if no parens needed)
|
||||
// "a ? 0 : 1" => "+!a" (if no parens needed)
|
||||
match (
|
||||
expr.consequent
|
||||
.evaluate_value(ctx)
|
||||
consequent_value
|
||||
.and_then(ConstantValue::into_number)
|
||||
.filter(|_| !expr.consequent.may_have_side_effects(ctx)),
|
||||
expr.alternate
|
||||
.evaluate_value(ctx)
|
||||
alternate_value
|
||||
.and_then(ConstantValue::into_number)
|
||||
.filter(|_| !expr.alternate.may_have_side_effects(ctx)),
|
||||
) {
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
File | File size || Sys allocs | Sys reallocs || Arena allocs | Arena reallocs
|
||||
---------------------------------------------------------------------------------------------------------------------------
|
||||
checker.ts | 2.92 MB || 166 | 52 || 152742 | 28244
|
||||
checker.ts | 2.92 MB || 162 | 52 || 152742 | 28244
|
||||
|
||||
App.tsx | 415.34 kB || 115 | 49 || 17012 | 2702
|
||||
|
||||
RadixUIAdoptionSection.jsx | 2.52 kB || 24 | 20 || 32 | 6
|
||||
|
||||
pdf.mjs | 567.30 kB || 2614 | 249 || 47485 | 7740
|
||||
pdf.mjs | 567.30 kB || 2613 | 249 || 47485 | 7740
|
||||
|
||||
antd.js | 6.69 MB || 3084 | 106 || 337233 | 69333
|
||||
|
||||
|
||||
Reference in new issue
Block a user