diff options
author | Aspen Smith <root@gws.fyi> | 2024-07-28T16·36-0400 |
---|---|---|
committer | aspen <root@gws.fyi> | 2024-08-08T00·02+0000 |
commit | 6559ab4cf5bb81fcf13578da6c9978f61ea56204 (patch) | |
tree | be77c191dfacfc1fa448af65cbb8c6a91997ce58 | |
parent | 6366cee717d47dc002d874b0c3eab2182e6cf55f (diff) |
feat(tvix/eval): Put interner in a thread-local RefCell r/8455
Rather than making the interner be a global lazy_static mutex, put it in a thread-local RefCell. This doesn't change anything in terms of sharing (since we're currently actually just single threaded), but avoids the overhead of a mutex, for a nice performance boost (compared to the mutex version): hello outpath time: [726.71 ms 729.79 ms 735.69 ms] change: [-5.7277% -3.9733% -2.1144%] (p = 0.00 < 0.05) Performance has improved. Change-Id: I240b238dcbaf854ebafc3017b4425fb7d7b91b03 Reviewed-on: https://cl.tvl.fyi/c/depot/+/12048 Tested-by: BuildkiteCI Reviewed-by: flokli <flokli@flokli.de> Autosubmit: aspen <root@gws.fyi>
-rw-r--r-- | tvix/eval/src/value/string.rs | 17 |
1 files changed, 8 insertions, 9 deletions
diff --git a/tvix/eval/src/value/string.rs b/tvix/eval/src/value/string.rs index 7fcdad413466..0365f5a9be77 100644 --- a/tvix/eval/src/value/string.rs +++ b/tvix/eval/src/value/string.rs @@ -4,18 +4,17 @@ //! level, allowing us to shave off some memory overhead and only //! paying the cost when creating new strings. use bstr::{BStr, BString, ByteSlice, Chars}; -use lazy_static::lazy_static; use rnix::ast; use rustc_hash::{FxHashMap, FxHashSet}; use std::alloc::dealloc; use std::alloc::{alloc, handle_alloc_error, Layout}; use std::borrow::{Borrow, Cow}; +use std::cell::RefCell; use std::ffi::c_void; use std::fmt::{self, Debug, Display}; use std::hash::Hash; use std::ops::Deref; use std::ptr::{self, NonNull}; -use std::sync::Mutex; use std::{mem, slice}; use serde::de::{Deserializer, Visitor}; @@ -423,21 +422,21 @@ impl InternerInner { } #[derive(Default)] -struct Interner(Mutex<InternerInner>); +struct Interner(RefCell<InternerInner>); impl Interner { pub fn intern(&self, s: &[u8]) -> NixString { - self.0.lock().unwrap().intern(s) + self.0.borrow_mut().intern(s) } #[cfg(feature = "no_leak")] pub fn is_interned_string(&self, string: &NixString) -> bool { - self.0.lock().unwrap().interned_strings.contains(&string.0) + self.0.borrow().interned_strings.contains(&string.0) } } -lazy_static! { - static ref INTERNER: Interner = Interner::default(); +thread_local! { + static INTERNER: Interner = Interner::default(); } /// Nix string values @@ -472,7 +471,7 @@ impl Drop for NixString { #[cfg(feature = "no_leak")] fn drop(&mut self) { - if INTERNER.is_interned_string(self) { + if INTERNER.with(|i| i.is_interned_string(self)) { return; } @@ -724,7 +723,7 @@ impl NixString { && contents.len() <= INTERN_THRESHOLD && context.is_none() { - return INTERNER.intern(contents); + return INTERNER.with(|i| i.intern(contents)); } Self::new_inner(contents, context) |