From 595c5df7629ec39fa137f9da0c56decfd21c8fd4 Mon Sep 17 00:00:00 2001 From: Dunqing <29533304+Dunqing@users.noreply.github.com> Date: Wed, 16 Apr 2025 13:28:48 +0000 Subject: [PATCH] perf(transformer/object_rest_spread): use `ArenaVec` to store values that will be used in constructing AST (#10434) `props` is always used in `expression_object` without intermediate changes, so it is okay and good to use `ArenaVec` store, which also can avoid an unnecessary allocation (std vec -> arena vec converison). --- .../oxc_transformer/src/es2018/object_rest_spread.rs | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/crates/oxc_transformer/src/es2018/object_rest_spread.rs b/crates/oxc_transformer/src/es2018/object_rest_spread.rs index fe6fc243bcb4c..17fc17b088661 100644 --- a/crates/oxc_transformer/src/es2018/object_rest_spread.rs +++ b/crates/oxc_transformer/src/es2018/object_rest_spread.rs @@ -488,7 +488,7 @@ impl<'a, 'ctx> ObjectRestSpread<'a, 'ctx> { } let mut call_expr: Option> = None; - let mut props = vec![]; + let mut props = ctx.ast.vec_with_capacity(obj_expr.properties.len()); for prop in obj_expr.properties.drain(..) { if let ObjectPropertyKind::SpreadProperty(spread_prop) = prop { @@ -509,12 +509,16 @@ impl<'a, 'ctx> ObjectRestSpread<'a, 'ctx> { fn make_object_spread( expr: &mut Option>, - props: &mut Vec>, + props: &mut ArenaVec<'a, ObjectPropertyKind<'a>>, transform_ctx: &'ctx TransformCtx<'a>, ctx: &mut TraverseCtx<'a>, ) { let had_props = !props.is_empty(); - let obj = ctx.ast.expression_object(SPAN, ctx.ast.vec_from_iter(props.drain(..))); + let obj = ctx.ast.expression_object( + SPAN, + // Reserve maximize might be used space for new vec + mem::replace(props, ctx.ast.vec_with_capacity(props.capacity() - props.len())), + ); let arguments = if let Some(call_expr) = expr.take() { let arg = Expression::CallExpression(ctx.ast.alloc(call_expr)); let arg = Argument::from(arg);