feat(tvix/eval): builtins.replaceStrings: don't clone() N times

CL/7034 looks great, except that for a length-N target string it
will perform N deep copies of each of the from and to-lists.  Let's
use references instead of clones.

Signed-off-by: Adam Joseph <adam@westernsemico.com>
Change-Id: Icd341213a9f0e728f9c8453cec6d23af5e1dea91
Reviewed-on: https://cl.tvl.fyi/c/depot/+/7095
Reviewed-by: wpcarro <wpcarro@gmail.com>
Reviewed-by: j4m3s <james.landrein@gmail.com>
Reviewed-by: tazjin <tazjin@tvl.su>
Tested-by: BuildkiteCI
This commit is contained in:
Adam Joseph 2022-10-26 02:03:19 -07:00 committed by clbot
parent ccab9c06a2
commit b8a7dba709

View file

@ -558,8 +558,10 @@ fn pure_builtins() -> Vec<Builtin> {
"replaceStrings",
&[true, true, true],
|args: Vec<Value>, vm: &mut VM| {
let from = args[0].to_list()?.into_iter();
let to = args[1].to_list()?.into_iter();
let from = args[0].to_list()?;
from.force_elements(vm)?;
let to = args[1].to_list()?;
to.force_elements(vm)?;
let string = args[2].to_str()?;
let mut res = String::new();
@ -575,9 +577,9 @@ fn pure_builtins() -> Vec<Builtin> {
// on every call which is not preferable.
'outer: while i < string.len() {
// Try a match in all the from strings
for elem in std::iter::zip(from.clone(), to.clone()) {
let from = elem.0.force(vm)?.to_str()?;
let to = elem.1.force(vm)?.to_str()?;
for elem in std::iter::zip(from.iter(), to.iter()) {
let from = elem.0.to_str()?;
let to = elem.1.to_str()?;
if i + from.len() >= string.len() {
continue;
@ -613,9 +615,9 @@ fn pure_builtins() -> Vec<Builtin> {
// Special case when the string is empty or at the string's end
// and one of the from is also empty
for elem in std::iter::zip(from.clone(), to.clone()) {
let from = elem.0.force(vm)?.to_str()?;
let to = elem.1.force(vm)?.to_str()?;
for elem in std::iter::zip(from.iter(), to.iter()) {
let from = elem.0.to_str()?;
let to = elem.1.to_str()?;
if from.as_str().len() == 0 {
res += &to;