From a0907d10acac427158c4fc0796c88b1bf7c4668a Mon Sep 17 00:00:00 2001 From: Tim Fennis Date: Sun, 24 May 2026 18:02:44 +0200 Subject: [PATCH] =?UTF-8?q?perf(vm):=20swap=20Box=20for=20Rc=20in=20Functi?= =?UTF-8?q?on::Memoized=20inner=20function=20=F0=9F=A7=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cloning Function::Memoized previously deep-cloned the boxed inner function on every callsite (resolve_callee). Switching to Rc makes the per-call clone a refcount bump; the inner is only cloned on cache miss via Rc::unwrap_or_clone. Micro-benchmarks (10M memoized calls, 99% cache hits): - compiled body: 1.66s → 1.57s (1.06×) - closure body: 1.71s → 1.59s (1.08×) Co-Authored-By: Claude Opus 4.7 (1M context) --- ndc_vm/src/value/function.rs | 2 +- ndc_vm/src/vm.rs | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/ndc_vm/src/value/function.rs b/ndc_vm/src/value/function.rs index c45baad4..5d4a7ebe 100644 --- a/ndc_vm/src/value/function.rs +++ b/ndc_vm/src/value/function.rs @@ -19,7 +19,7 @@ pub enum Function { Memoized { cache: Rc>>, - function: Box, + function: Rc, }, } diff --git a/ndc_vm/src/vm.rs b/ndc_vm/src/vm.rs index d682dd6f..d4068139 100644 --- a/ndc_vm/src/vm.rs +++ b/ndc_vm/src/vm.rs @@ -555,7 +555,7 @@ impl Vm { let func = func.clone(); self.stack.push(Value::function(Function::Memoized { cache: Rc::new(RefCell::new(HashMap::default())), - function: Box::new(func), + function: Rc::new(func), })); } } @@ -625,7 +625,7 @@ impl Vm { // Cache miss: dispatch the inner function and remember to store // the result in the cache when this frame returns. - self.dispatch_call_with_memo(*function, args, Some((cache, key))) + self.dispatch_call_with_memo(Rc::unwrap_or_clone(function), args, Some((cache, key))) } else { self.dispatch_call_with_memo(func, args, None) }