Reduce size of Expr from 80 to 64 bytes (#9900)

## Summary

This PR reduces the size of `Expr` from 80 to 64 bytes, by reducing the
sizes of...

- `ExprCall` from 72 to 56 bytes, by using boxed slices for `Arguments`.
- `ExprCompare` from 64 to 48 bytes, by using boxed slices for its
various vectors.

In testing, the parser gets a bit faster, and the linter benchmarks
improve quite a bit.
This commit is contained in:
Charlie Marsh 2024-02-08 18:53:13 -08:00 committed by GitHub
parent bd8123c0d8
commit 49fe1b85f2
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
78 changed files with 326 additions and 258 deletions

View file

@ -52,12 +52,12 @@ where
// Accept empty initializers.
if let Expr::Call(ast::ExprCall {
func,
arguments: Arguments { args, keywords, .. },
arguments,
range: _,
}) = expr
{
// Ex) `list()`
if args.is_empty() && keywords.is_empty() {
if arguments.is_empty() {
if let Expr::Name(ast::ExprName { id, .. }) = func.as_ref() {
if !is_iterable_initializer(id.as_str(), |id| is_builtin(id)) {
return true;
@ -221,14 +221,14 @@ pub fn any_over_expr(expr: &Expr, func: &dyn Fn(&Expr) -> bool) -> bool {
}) => any_over_expr(left, func) || comparators.iter().any(|expr| any_over_expr(expr, func)),
Expr::Call(ast::ExprCall {
func: call_func,
arguments: Arguments { args, keywords, .. },
arguments,
range: _,
}) => {
any_over_expr(call_func, func)
// Note that this is the evaluation order but not necessarily the declaration order
// (e.g. for `f(*args, a=2, *args2, **kwargs)` it's not)
|| args.iter().any(|expr| any_over_expr(expr, func))
|| keywords
|| arguments.args.iter().any(|expr| any_over_expr(expr, func))
|| arguments.keywords
.iter()
.any(|keyword| any_over_expr(&keyword.value, func))
}
@ -1227,18 +1227,16 @@ impl Truthiness {
}
}
Expr::Call(ast::ExprCall {
func,
arguments: Arguments { args, keywords, .. },
..
func, arguments, ..
}) => {
if let Expr::Name(ast::ExprName { id, .. }) = func.as_ref() {
if is_iterable_initializer(id.as_str(), |id| is_builtin(id)) {
if args.is_empty() && keywords.is_empty() {
if arguments.is_empty() {
// Ex) `list()`
Self::Falsey
} else if args.len() == 1 && keywords.is_empty() {
} else if arguments.args.len() == 1 && arguments.keywords.is_empty() {
// Ex) `list([1, 2, 3])`
Self::from_expr(&args[0], is_builtin)
Self::from_expr(&arguments.args[0], is_builtin)
} else {
Self::Unknown
}