difftreelog
perf faster std.map
in: master
3 files changed
crates/jrsonnet-evaluator/build.rsdiffbeforeafterboth40 name == "base64" || name == "foldl" || name == "foldr" ||40 name == "base64" || name == "foldl" || name == "foldr" ||41 name == "sortImpl" || name == "format" || name == "range" ||41 name == "sortImpl" || name == "format" || name == "range" ||42 name == "reverse" || name == "slice" || name == "mod" ||42 name == "reverse" || name == "slice" || name == "mod" ||43 name == "strReplace"43 name == "strReplace" || name == "map"44 )44 )45 })45 })46 .collect(),46 .collect(),crates/jrsonnet-evaluator/src/builtin/mod.rsdiffbeforeafterboth--- a/crates/jrsonnet-evaluator/src/builtin/mod.rs
+++ b/crates/jrsonnet-evaluator/src/builtin/mod.rs
@@ -57,6 +57,7 @@
("extVar".into(), builtin_ext_var),
("native".into(), builtin_native),
("filter".into(), builtin_filter),
+ ("map".into(), builtin_map),
("foldl".into(), builtin_foldl),
("foldr".into(), builtin_foldr),
("sortImpl".into(), builtin_sort_impl),
@@ -294,16 +295,19 @@
0, func: ty!(function) => Val::Func;
1, arr: ty!(array) => Val::Arr;
], {
- let mut out = Vec::new();
- for item in arr.iter() {
- let item = item?;
- if func
- .evaluate_values(context.clone(), &[item.clone()])?
- .try_cast_bool("filter predicate")? {
- out.push(item);
- }
- }
- Ok(Val::Arr(out.into()))
+ Ok(Val::Arr(arr.filter(|val| func
+ .evaluate_values(context.clone(), &[val.clone()])?
+ .try_cast_bool("filter predicate"))?))
+ })
+}
+
+fn builtin_map(context: Context, _loc: Option<&ExprLocation>, args: &ArgsDesc) -> Result<Val> {
+ parse_args!(context, "map", args, 2, [
+ 0, func: ty!(function) => Val::Func;
+ 1, arr: ty!(array) => Val::Arr;
+ ], {
+ Ok(Val::Arr(arr.map(|val| func
+ .evaluate_values(context.clone(), &[val]))?))
})
}
crates/jrsonnet-evaluator/src/val.rsdiffbeforeafterboth--- a/crates/jrsonnet-evaluator/src/val.rs
+++ b/crates/jrsonnet-evaluator/src/val.rs
@@ -283,6 +283,29 @@
}
}
+ pub fn map(self, mapper: impl Fn(Val) -> Result<Val>) -> Result<Self> {
+ let mut out = Vec::with_capacity(self.len());
+
+ for value in self.iter() {
+ out.push(mapper(value?)?);
+ }
+
+ Ok(Self::Eager(Rc::new(out)))
+ }
+
+ pub fn filter(self, filter: impl Fn(&Val) -> Result<bool>) -> Result<Self> {
+ let mut out = Vec::with_capacity(self.len());
+
+ for value in self.iter() {
+ let value = value?;
+ if filter(&value)? {
+ out.push(value);
+ }
+ }
+
+ Ok(Self::Eager(Rc::new(out)))
+ }
+
pub fn ptr_eq(a: &Self, b: &Self) -> bool {
match (a, b) {
(Self::Lazy(a), Self::Lazy(b)) => Rc::ptr_eq(a, b),