From e3c92ac3b4b07a7397b565738ec4237b9bf621f6 Mon Sep 17 00:00:00 2001 From: Aspen Smith Date: Sat, 10 Feb 2024 11:29:58 -0500 Subject: fix(tvix/eval): Replace inner NixString repr with Box Storing a full BString here incurs the extra overhead of the capacity for the inner byte-vector, which we basically never use as Nix strings are immutable (and we don't do any mutation / sharing analysis). Switching to a Box cuts us from 72 bytes to 64 bytes per string (and there are a lot of strings!) Change-Id: I11f34c14a08fa02759f260b1c78b2a2b981714e4 Reviewed-on: https://cl.tvl.fyi/c/depot/+/10794 Autosubmit: aspen Reviewed-by: flokli Tested-by: BuildkiteCI --- tvix/eval/src/builtins/mod.rs | 46 ++++++++++++++++++++----------------------- 1 file changed, 21 insertions(+), 25 deletions(-) (limited to 'tvix/eval/src/builtins') diff --git a/tvix/eval/src/builtins/mod.rs b/tvix/eval/src/builtins/mod.rs index 3048b32fb550..a0b990ec542c 100644 --- a/tvix/eval/src/builtins/mod.rs +++ b/tvix/eval/src/builtins/mod.rs @@ -3,7 +3,7 @@ //! See //tvix/eval/docs/builtins.md for a some context on the //! available builtins in Nix. -use bstr::ByteVec; +use bstr::{ByteSlice, ByteVec}; use builtin_macros::builtins; use genawaiter::rc::Gen; use imbl::OrdMap; @@ -67,7 +67,7 @@ pub async fn coerce_value_to_path( .await { Ok(vs) => { - let path = (**vs).clone().into_path_buf()?; + let path = vs.to_path()?.to_owned(); if path.is_absolute() { Ok(Ok(path)) } else { @@ -82,7 +82,7 @@ pub async fn coerce_value_to_path( mod pure_builtins { use std::ffi::OsString; - use bstr::{BString, ByteSlice}; + use bstr::{BString, ByteSlice, B}; use imbl::Vector; use itertools::Itertools; use os_str_bytes::OsStringBytes; @@ -171,26 +171,23 @@ mod pure_builtins { #[builtin("baseNameOf")] async fn builtin_base_name_of(co: GenCo, s: Value) -> Result { let span = generators::request_span(&co).await; - let mut s = match s { - val @ Value::Catchable(_) => return Ok(val), - _ => s - .coerce_to_string( - co, - CoercionKind { - strong: false, - import_paths: false, - }, - span, - ) - .await? - .to_contextful_str()?, - }; + let s = s + .coerce_to_string( + co, + CoercionKind { + strong: false, + import_paths: false, + }, + span, + ) + .await? + .to_contextful_str()?; - let bs = s.as_mut_bstring(); + let mut bs = (**s).to_owned(); if let Some(last_slash) = bs.rfind_char('/') { - *bs = bs[(last_slash + 1)..].into(); + bs = bs[(last_slash + 1)..].into(); } - Ok(s.into()) + Ok(NixString::new_inherit_context_from(&s, bs).into()) } #[builtin("bitAnd")] @@ -344,7 +341,7 @@ mod pure_builtins { .map(|last_slash| { let x = &str[..last_slash]; if x.is_empty() { - b"/" + B("/") } else { x } @@ -356,8 +353,7 @@ mod pure_builtins { )))) } else { Ok(Value::from(NixString::new_inherit_context_from( - &str, - result.into(), + &str, result, ))) } } @@ -1190,7 +1186,7 @@ mod pure_builtins { // push the unmatched characters preceding the match ret.push_back(Value::from(NixString::new_inherit_context_from( &s, - (&text[pos..thematch.start()]).into(), + &text[pos..thematch.start()], ))); // Push a list with one element for each capture @@ -1363,7 +1359,7 @@ mod pure_builtins { Ok(Value::from(NixString::new_inherit_context_from( &x, - (&x[beg..end]).into(), + &x[beg..end], ))) } -- cgit 1.4.1