perf(react_compiler): use faster API to arena allocate strings (#23849)

Small perf optimization to React Compiler.

Replace `ArenaStringBuilder::from_str_in(s, self.allocator).into_str()` with `Str::from_str_in(s, self)`.

The latter is faster - `ArenaStringBuilder` is designed for building up a string from multiple parts. Here we just want to allocate a single string, so `Str::from_str_in` is faster, and simpler. Using `ArenaStringBuilder` was a weird choice. 🚨 Slop alert! 🚨

Also, return a `Str<'a>`. There's no advantage to coverting to a `&str`, and this removes having to convert _back_ to a `Str` elsewhere.
This commit is contained in:
overlookmotel committed 2026-06-26 19:24:28 +00:00
1 parent 065baf8a19
commit 3ea9304bd4
3 files changed
+11 -9

No files matched your search

Generated
+1
View File
@@ -2511,6 +2511,7 @@ dependencies = [
"oxc_parser",
"oxc_semantic",
"oxc_span",
"oxc_str",
"oxc_syntax",
"rustc-hash",
"serde_json",
+1
View File
@@ -35,6 +35,7 @@ oxc_diagnostics = { workspace = true }
oxc_parser = { workspace = true }
oxc_semantic = { workspace = true }
oxc_span = { workspace = true }
oxc_str = { workspace = true }
oxc_syntax = { workspace = true }
# React Compiler core crates — frontend-agnostic (no oxc deps). Published fork of
@@ -15,6 +15,7 @@ use oxc_ast::builder::{AstBuilder, GetAstBuilder};
use oxc_ast_visit::VisitMut;
use oxc_span::SPAN;
use oxc_span::Span;
use oxc_str::Str;
use oxc_syntax::identifier::is_identifier_name;
use react_compiler_ast::common::BaseNode;
use react_compiler_ast::declarations::*;
@@ -985,12 +986,12 @@ impl<'a> ReverseCtx<'a> {
.is_some_and(|text| text.trim_start().starts_with("interface"))
}
/// Allocate a string in the arena and return a `&str` with lifetime 'a.
/// Allocate a string in the arena and return a `Str<'a>`.
///
/// The returned `&'a str` converts into both `Ident` and `Str` (identifier
/// and string-literal name types), so it feeds every `AstBuilder` method.
fn str(&self, s: &str) -> &'a str {
oxc_allocator::ArenaStringBuilder::from_str_in(s, self.allocator).into_str()
/// `Str<'a>` converts to `Ident<'a>`, so can be passed to any `AstBuilder` method.
#[inline]
fn str(&self, s: &str) -> Str<'a> {
Str::from_str_in(s, self)
}
/// Convert a BaseNode's start/end into an OXC Span.
@@ -1432,8 +1433,7 @@ impl<'a> ReverseCtx<'a> {
),
Expression::RegExpLiteral(lit) => {
let flags = self.parse_regexp_flags(&lit.flags);
let pattern =
oxc::RegExpPattern { text: self.str(&lit.pattern).into(), pattern: None };
let pattern = oxc::RegExpPattern { text: self.str(&lit.pattern), pattern: None };
let regex = oxc::RegExp { pattern, flags };
oxc::Expression::new_reg_exp_literal(SPAN, regex, None, self)
}
@@ -2019,8 +2019,8 @@ impl<'a> ReverseCtx<'a> {
) -> oxc::TemplateLiteral<'a> {
let quasis = ArenaVec::from_iter_in(
tl.quasis.iter().map(|q| {
let raw = self.str(&q.value.raw).into();
let cooked = q.value.cooked.as_ref().map(|c| self.str(c).into());
let raw = self.str(&q.value.raw);
let cooked = q.value.cooked.as_ref().map(|c| self.str(c));
let value = oxc::TemplateElementValue { raw, cooked };
oxc::TemplateElement::new(SPAN, value, q.tail, self)
}),