mirror of
https://github.com/danbulant/oxc
synced 2026-05-24 12:21:58 +00:00
perf(transformer/react-refresh): avoid allocating string in each hook call (#8013)
related: https://github.com/oxc-project/oxc/pull/7970#issuecomment-2551294930; Just realized this can be simplified to that
This commit is contained in:
parent
e7476a1a28
commit
7b703471b1
1 changed files with 29 additions and 17 deletions
|
|
@ -1,5 +1,6 @@
|
||||||
|
use std::collections::hash_map::Entry;
|
||||||
|
|
||||||
use base64::prelude::{Engine, BASE64_STANDARD};
|
use base64::prelude::{Engine, BASE64_STANDARD};
|
||||||
use compact_str::{CompactString, CompactStringExt};
|
|
||||||
use rustc_hash::FxHashMap;
|
use rustc_hash::FxHashMap;
|
||||||
use sha1::{Digest, Sha1};
|
use sha1::{Digest, Sha1};
|
||||||
|
|
||||||
|
|
@ -111,8 +112,8 @@ pub struct ReactRefresh<'a, 'ctx> {
|
||||||
/// Used to wrap call expression with signature.
|
/// Used to wrap call expression with signature.
|
||||||
/// (eg: hoc(() => {}) -> _s1(hoc(_s1(() => {}))))
|
/// (eg: hoc(() => {}) -> _s1(hoc(_s1(() => {}))))
|
||||||
last_signature: Option<(BindingIdentifier<'a>, ArenaVec<'a, Argument<'a>>)>,
|
last_signature: Option<(BindingIdentifier<'a>, ArenaVec<'a, Argument<'a>>)>,
|
||||||
// (function_scope_id, (hook_name, hook_key, custom_hook_callee)
|
// (function_scope_id, key)
|
||||||
hook_calls: FxHashMap<ScopeId, Vec<CompactString>>,
|
function_signature_keys: FxHashMap<ScopeId, String>,
|
||||||
non_builtin_hooks_callee: FxHashMap<ScopeId, Vec<Option<Expression<'a>>>>,
|
non_builtin_hooks_callee: FxHashMap<ScopeId, Vec<Option<Expression<'a>>>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -129,7 +130,7 @@ impl<'a, 'ctx> ReactRefresh<'a, 'ctx> {
|
||||||
registrations: Vec::default(),
|
registrations: Vec::default(),
|
||||||
ctx,
|
ctx,
|
||||||
last_signature: None,
|
last_signature: None,
|
||||||
hook_calls: FxHashMap::default(),
|
function_signature_keys: FxHashMap::default(),
|
||||||
non_builtin_hooks_callee: FxHashMap::default(),
|
non_builtin_hooks_callee: FxHashMap::default(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -378,19 +379,31 @@ impl<'a, 'ctx> Traverse<'a> for ReactRefresh<'a, 'ctx> {
|
||||||
} else {
|
} else {
|
||||||
""
|
""
|
||||||
};
|
};
|
||||||
|
|
||||||
let is_empty = args_key.is_empty();
|
let is_empty = args_key.is_empty();
|
||||||
// `hook_name{{declarator_id(args_key)}}` or `hook_name{{declarator_id}}`
|
// `hook_name{{declarator_id(args_key)}}` or `hook_name{{declarator_id}}`
|
||||||
let key = [
|
let push_key_to_string = |string: &mut String| {
|
||||||
hook_name.as_str(),
|
string.push_str(hook_name.as_str());
|
||||||
"{",
|
string.push('{');
|
||||||
declarator_id,
|
string.push_str(declarator_id);
|
||||||
if is_empty { "" } else { "(" },
|
string.push_str(if is_empty { "" } else { "(" });
|
||||||
args_key,
|
string.push_str(args_key);
|
||||||
if is_empty { "" } else { ")" },
|
string.push_str(if is_empty { "" } else { ")" });
|
||||||
"}",
|
string.push('}');
|
||||||
]
|
};
|
||||||
.concat_compact();
|
|
||||||
self.hook_calls.entry(current_scope_id).or_default().push(key);
|
match self.function_signature_keys.entry(current_scope_id) {
|
||||||
|
Entry::Occupied(mut entry) => {
|
||||||
|
let string = entry.get_mut();
|
||||||
|
string.push_str("\\n");
|
||||||
|
push_key_to_string(string);
|
||||||
|
}
|
||||||
|
Entry::Vacant(entry) => {
|
||||||
|
let mut string = String::new();
|
||||||
|
push_key_to_string(&mut string);
|
||||||
|
entry.insert(string);
|
||||||
|
}
|
||||||
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -515,9 +528,8 @@ impl<'a, 'ctx> ReactRefresh<'a, 'ctx> {
|
||||||
body: &mut FunctionBody<'a>,
|
body: &mut FunctionBody<'a>,
|
||||||
ctx: &mut TraverseCtx<'a>,
|
ctx: &mut TraverseCtx<'a>,
|
||||||
) -> Option<(BindingIdentifier<'a>, ArenaVec<'a, Argument<'a>>)> {
|
) -> Option<(BindingIdentifier<'a>, ArenaVec<'a, Argument<'a>>)> {
|
||||||
let fn_hook_calls = self.hook_calls.remove(&scope_id)?;
|
let mut key = self.function_signature_keys.remove(&scope_id)?;
|
||||||
|
|
||||||
let mut key = fn_hook_calls.join("\\n");
|
|
||||||
if !self.emit_full_signatures {
|
if !self.emit_full_signatures {
|
||||||
// Prefer to hash when we can (e.g. outside of ASTExplorer).
|
// Prefer to hash when we can (e.g. outside of ASTExplorer).
|
||||||
// This makes it deterministically compact, even if there's
|
// This makes it deterministically compact, even if there's
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue