From 9fa8ae5b5f8fb0dde20f255590bbc9e0d1c9466f Mon Sep 17 00:00:00 2001 From: pjh456 <147148383@qq.com> Date: Mon, 10 Aug 2026 17:40:39 +0800 Subject: [PATCH] =?UTF-8?q?perf:=20=E5=AD=97=E7=AC=A6=E4=B8=B2=E6=8B=BC?= =?UTF-8?q?=E6=8E=A5=E6=8C=89=E6=93=8D=E4=BD=9C=E6=95=B0=E5=AD=97=E8=8A=82?= =?UTF-8?q?=E9=95=BF=E9=A2=84=E5=88=86=E9=85=8D=E5=AE=B9=E9=87=8F=EF=BC=8C?= =?UTF-8?q?=E5=85=8D=E5=87=A0=E4=BD=95=20realloc=20=E4=BA=8C=E6=AC=A1?= =?UTF-8?q?=E6=8B=B7=E8=B4=9D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- crates/oxide_vm/src/dispatch/arithmetic.rs | 20 ++++++++++++++------ crates/oxide_vm/src/vm.rs | 2 -- crates/oxide_vm/src/vm_support.rs | 2 -- 3 files changed, 14 insertions(+), 10 deletions(-) diff --git a/crates/oxide_vm/src/dispatch/arithmetic.rs b/crates/oxide_vm/src/dispatch/arithmetic.rs index c3d60a9c..a20082c2 100644 --- a/crates/oxide_vm/src/dispatch/arithmetic.rs +++ b/crates/oxide_vm/src/dispatch/arithmetic.rs @@ -16,12 +16,16 @@ impl Vm { let lhs = self.coerce_primitive_bounded(lv, false)?; let rhs = self.coerce_primitive_bounded(rv, false)?; if lhs.is_string() || rhs.is_string() { - let mut buf = std::mem::take(&mut self.string_buf); - buf.clear(); + let lbytes = if lhs.is_string() { unsafe { (*lhs.as_string_ptr()).len() } } else { 0 }; + let rbytes = if rhs.is_string() { unsafe { (*rhs.as_string_ptr()).len() } } else { 0 }; + // 预分配精确容量:字符串操作数 O(1) 取字节长,一次分配写齐,免 push_str + // 几何 realloc 的二次拷贝(字符串拼接热路径的主要额外成本)。 + // 32 字节余量覆盖数字/布尔等格式化文本(f64 文本最长约 24 字节), + // 避免追加非字符串操作数时二次扩容。 + let mut buf = String::with_capacity(lbytes + rbytes + 32); coercion::push_to_string(lhs, &mut buf); coercion::push_to_string(rhs, &mut buf); let result = self.new_string_owned(buf); - self.string_buf = String::new(); self.regs[rd] = result; } else { let ln = coercion::to_number(lhs); @@ -58,12 +62,16 @@ impl Vm { let lhs = self.coerce_primitive_bounded(lv, false)?; let rhs = self.coerce_primitive_bounded(rv, false)?; if lhs.is_string() || rhs.is_string() { - let mut buf = std::mem::take(&mut self.string_buf); - buf.clear(); + let lbytes = if lhs.is_string() { unsafe { (*lhs.as_string_ptr()).len() } } else { 0 }; + let rbytes = if rhs.is_string() { unsafe { (*rhs.as_string_ptr()).len() } } else { 0 }; + // 预分配精确容量:字符串操作数 O(1) 取字节长,一次分配写齐,免 push_str + // 几何 realloc 的二次拷贝(字符串拼接热路径的主要额外成本)。 + // 32 字节余量覆盖数字/布尔等格式化文本(f64 文本最长约 24 字节), + // 避免追加非字符串操作数时二次扩容。 + let mut buf = String::with_capacity(lbytes + rbytes + 32); coercion::push_to_string(lhs, &mut buf); coercion::push_to_string(rhs, &mut buf); let result = self.new_string_owned(buf); - self.string_buf = String::new(); self.regs[rd] = result; } else { let ln = coercion::to_number(lhs); diff --git a/crates/oxide_vm/src/vm.rs b/crates/oxide_vm/src/vm.rs index 3a2fb34a..fc0fb94a 100644 --- a/crates/oxide_vm/src/vm.rs +++ b/crates/oxide_vm/src/vm.rs @@ -348,8 +348,6 @@ pub struct Vm { /// 分组保存 inline cache 与指令计数器。 pub(crate) profiling: ProfilingState, pub(crate) cell_stack: Vec>, - /// 可复用字符串缓冲区,避免每次 `+` 拼接都分配。 - pub(crate) string_buf: String, } impl Vm { diff --git a/crates/oxide_vm/src/vm_support.rs b/crates/oxide_vm/src/vm_support.rs index 169f1afc..d5a9f4d3 100644 --- a/crates/oxide_vm/src/vm_support.rs +++ b/crates/oxide_vm/src/vm_support.rs @@ -97,7 +97,6 @@ impl Vm { ic_misses: std::cell::Cell::new(0), instruction_count: 0, }, - string_buf: String::new(), cell_stack: Vec::new(), }; vm.init_generator_intrinsics(); @@ -190,7 +189,6 @@ impl Vm { ic_misses: std::cell::Cell::new(0), instruction_count: 0, }, - string_buf: String::new(), cell_stack: Vec::new(), }; vm.init_generator_intrinsics();