feat(minifier): minify exponential arithmetic operation. (#6281)

This commit is contained in:
7086cmd 2024-10-07 12:59:27 +00:00
parent ac5a23fd34
commit e304e8cd2b

View file

@ -493,7 +493,12 @@ impl<'a> PeepholeFoldConstants {
operation: &mut BinaryExpression<'a>, operation: &mut BinaryExpression<'a>,
ctx: &mut TraverseCtx<'a>, ctx: &mut TraverseCtx<'a>,
) -> Option<Expression<'a>> { ) -> Option<Expression<'a>> {
fn shorter_than_original(result: f64, left: f64, right: f64) -> bool { fn shorter_than_original(
result: f64,
left: f64,
right: f64,
length_of_operator: usize,
) -> bool {
if result > MAX_SAFE_FLOAT if result > MAX_SAFE_FLOAT
|| result < NEG_MAX_SAFE_FLOAT || result < NEG_MAX_SAFE_FLOAT
|| result.is_nan() || result.is_nan()
@ -502,7 +507,8 @@ impl<'a> PeepholeFoldConstants {
return false; return false;
} }
let result_str = result.to_string().len(); let result_str = result.to_string().len();
let original_str = left.to_string().len() + right.to_string().len() + 1; let original_str =
left.to_string().len() + right.to_string().len() + length_of_operator;
result_str <= original_str result_str <= original_str
} }
if !operation.operator.is_arithmetic() { if !operation.operator.is_arithmetic() {
@ -518,7 +524,7 @@ impl<'a> PeepholeFoldConstants {
BinaryOperator::Subtraction => left - right, BinaryOperator::Subtraction => left - right,
BinaryOperator::Multiplication => { BinaryOperator::Multiplication => {
let result = left * right; let result = left * right;
if shorter_than_original(result, left, right) { if shorter_than_original(result, left, right, 1) {
result result
} else { } else {
return None; return None;
@ -529,14 +535,21 @@ impl<'a> PeepholeFoldConstants {
return None; return None;
} }
let result = left / right; let result = left / right;
if shorter_than_original(result, left, right) { if shorter_than_original(result, left, right, 1) {
result result
} else { } else {
return None; return None;
} }
} }
BinaryOperator::Remainder if !right.is_zero() && right.is_finite() => left % right, BinaryOperator::Remainder if !right.is_zero() && right.is_finite() => left % right,
// TODO BinaryOperator::Exponential if BinaryOperator::Exponential => {
let result = left.powf(right);
if shorter_than_original(result, left, right, 2) {
result
} else {
return None;
}
}
_ => return None, _ => return None,
}; };
let number_base = let number_base =
@ -1651,10 +1664,15 @@ mod test {
test_same("x = 1 % 0"); test_same("x = 1 % 0");
// We should not fold this because it's not safe to fold. // We should not fold this because it's not safe to fold.
test_same(format!("x = {} * {}", MAX_SAFE_INT / 2, MAX_SAFE_INT / 2).as_str()); test_same(format!("x = {} * {}", MAX_SAFE_INT / 2, MAX_SAFE_INT / 2).as_str());
// test("x = 2 ** 3", "x = 8");
// test("x = 2 ** -3", "x = 0.125"); test("x = 2 ** 3", "x = 8");
// test_same("x = 2 ** 55"); // backs off folding because 2 ** 55 is too large test("x = 2 ** -3", "x = 0.125");
// test_same("x = 3 ** -1"); // backs off because 3**-1 is shorter than 0.3333333333333333 test_same("x = 2 ** 55"); // backs off folding because 2 ** 55 is too large
test_same("x = 3 ** -1"); // backs off because 3**-1 is shorter than 0.3333333333333333
test_same("x = 0 / 0");
test_same("x = 0 % 0");
test_same("x = -1 ** 0.5");
} }
#[test] #[test]