mirror of
https://github.com/oxc-project/oxc.git
synced 2026-11-04 10:29:58 +00:00
perf(ast/estree): pre-allocate CodeBuffer for JSON output (#9340)
`ESTree` serialization pre-allocate capacity in `CodeBuffer` for JSON, based on an heuristic ratio of source text length to JSON length, to avoid the buffer having to grow during serialization.
This commit is contained in:
1 parent
018c52357a
commit
1bfc4595c5
2 files changed
+32
-4
No files matched your search
@@ -16,31 +16,54 @@ use crate::ast::*;
|
||||
///
|
||||
/// Most consumers (and Oxc crates) will use only 1 of these methods, so we don't want to needlessly
|
||||
/// compile all 4 serializers when only 1 is used.
|
||||
///
|
||||
/// Initial capacity for serializer's buffer is an estimate based on our benchmark fixtures
|
||||
/// of ratio of source text size to JSON size.
|
||||
///
|
||||
/// | File | Compact TS | Compact JS | Pretty TS | Pretty JS |
|
||||
/// |----------------------------|------------|------------|-----------|-----------|
|
||||
/// | antd.js | 10 | 9 | 76 | 72 |
|
||||
/// | cal.com.tsx | 10 | 9 | 40 | 37 |
|
||||
/// | checker.ts | 7 | 6 | 27 | 24 |
|
||||
/// | pdf.mjs | 13 | 12 | 71 | 67 |
|
||||
/// | RadixUIAdoptionSection.jsx | 10 | 9 | 45 | 44 |
|
||||
/// |----------------------------|------------|------------|-----------|-----------|
|
||||
/// | Maximum | 13 | 12 | 76 | 72 |
|
||||
///
|
||||
/// It's better to over-estimate than under-estimate, as having to grow the buffer is expensive,
|
||||
/// so have gone on the generous side.
|
||||
const JSON_CAPACITY_RATIO_COMPACT: usize = 16;
|
||||
const JSON_CAPACITY_RATIO_PRETTY: usize = 80;
|
||||
|
||||
impl Program<'_> {
|
||||
/// Serialize AST to ESTree JSON, including TypeScript fields.
|
||||
pub fn to_estree_ts_json(&self) -> String {
|
||||
let mut serializer = CompactTSSerializer::new();
|
||||
let capacity = self.source_text.len() * JSON_CAPACITY_RATIO_COMPACT;
|
||||
let mut serializer = CompactTSSerializer::with_capacity(capacity);
|
||||
self.serialize(&mut serializer);
|
||||
serializer.into_string()
|
||||
}
|
||||
|
||||
/// Serialize AST to ESTree JSON, without TypeScript fields.
|
||||
pub fn to_estree_js_json(&self) -> String {
|
||||
let mut serializer = CompactJSSerializer::new();
|
||||
let capacity = self.source_text.len() * JSON_CAPACITY_RATIO_COMPACT;
|
||||
let mut serializer = CompactJSSerializer::with_capacity(capacity);
|
||||
self.serialize(&mut serializer);
|
||||
serializer.into_string()
|
||||
}
|
||||
|
||||
/// Serialize AST to pretty-printed ESTree JSON, including TypeScript fields.
|
||||
pub fn to_pretty_estree_ts_json(&self) -> String {
|
||||
let mut serializer = PrettyTSSerializer::new();
|
||||
let capacity = self.source_text.len() * JSON_CAPACITY_RATIO_PRETTY;
|
||||
let mut serializer = PrettyTSSerializer::with_capacity(capacity);
|
||||
self.serialize(&mut serializer);
|
||||
serializer.into_string()
|
||||
}
|
||||
|
||||
/// Serialize AST to pretty-printed ESTree JSON, without TypeScript fields.
|
||||
pub fn to_pretty_estree_js_json(&self) -> String {
|
||||
let mut serializer = PrettyJSSerializer::new();
|
||||
let capacity = self.source_text.len() * JSON_CAPACITY_RATIO_PRETTY;
|
||||
let mut serializer = PrettyJSSerializer::with_capacity(capacity);
|
||||
self.serialize(&mut serializer);
|
||||
serializer.into_string()
|
||||
}
|
||||
|
||||
@@ -79,6 +79,11 @@ impl<C: Config, F: Formatter> ESTreeSerializer<C, F> {
|
||||
Self { buffer: CodeBuffer::new(), formatter: F::new(), config: C::new() }
|
||||
}
|
||||
|
||||
/// Create new [`ESTreeSerializer`] with specified buffer capacity.
|
||||
pub fn with_capacity(capacity: usize) -> Self {
|
||||
Self { buffer: CodeBuffer::with_capacity(capacity), formatter: F::new(), config: C::new() }
|
||||
}
|
||||
|
||||
/// Consume this [`ESTreeSerializer`] and convert buffer to string.
|
||||
pub fn into_string(self) -> String {
|
||||
self.buffer.into_string()
|
||||
|
||||
Reference in new issue
Block a user