git.delta.rocks / jrsonnet / refs/commits / ff10378ddbc9

difftreelog

perf faster std.map

Yaroslav Bolyukin2021-02-20parent: #643b007.patch.diff
in: master

3 files changed

modifiedcrates/jrsonnet-evaluator/build.rsdiffbeforeafterboth
40 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(),
modifiedcrates/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]))?))
 	})
 }
 
modifiedcrates/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),