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

difftreelog

perf implement std.findSubstr in native

Yaroslav Bolyukin2022-08-07parent: #0831da3.patch.diff
in: master

4 files changed

modifiedCargo.tomldiffbeforeafterboth
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -8,6 +8,6 @@
 opt-level = 3
 lto = "fat"
 codegen-units = 1
-# debug = 0
+debug = 0
 panic = "abort"
-# strip = true
+strip = true
modifiedcrates/jrsonnet-evaluator/src/val.rsdiffbeforeafterboth
206 pub fn new_eager() -> Self {206 pub fn new_eager() -> Self {
207 Self::Eager(Cc::new(Vec::new()))207 Self::Eager(Cc::new(Vec::new()))
208 }208 }
209 pub fn empty() -> Self {
210 Self::new_range(0, 0)
211 }
209212
210 /// # Panics213 /// # Panics
211 /// If a > b214 /// If a > b
215 #[inline]
212 pub fn new_range(a: i32, b: i32) -> Self {216 pub fn new_range(a: i32, b: i32) -> Self {
213 assert!(a <= b);217 assert!(a <= b);
214 Self::Range(a, b)218 Self::Range(a, b)
modifiedcrates/jrsonnet-stdlib/src/lib.rsdiffbeforeafterboth
--- a/crates/jrsonnet-stdlib/src/lib.rs
+++ b/crates/jrsonnet-stdlib/src/lib.rs
@@ -128,6 +128,7 @@
 		("splitLimit".into(), builtin_splitlimit::INST),
 		("asciiUpper".into(), builtin_ascii_upper::INST),
 		("asciiLower".into(), builtin_ascii_lower::INST),
+		("findSubstr".into(), builtin_find_substr::INST),
 	]
 	.iter()
 	.cloned()
@@ -420,3 +421,28 @@
 fn builtin_ascii_lower(str: IStr) -> Result<String> {
 	Ok(str.to_ascii_lowercase())
 }
+
+#[builtin]
+fn builtin_find_substr(pat: IStr, str: IStr) -> Result<ArrValue> {
+	if pat.is_empty() || str.is_empty() || pat.len() > str.len() {
+		return Ok(ArrValue::empty());
+	}
+
+	let str = str.as_str();
+	let pat = pat.as_bytes();
+	let strb = str.as_bytes();
+
+	let max_pos = str.len() - pat.len();
+
+	let mut out: Vec<Val> = Vec::new();
+	for (ch_idx, (i, _)) in str
+		.char_indices()
+		.take_while(|(i, _)| i <= &max_pos)
+		.enumerate()
+	{
+		if &strb[i..i + pat.len()] == pat {
+			out.push(Val::Num(ch_idx as f64))
+		}
+	}
+	Ok(out.into())
+}
modifiedcrates/jrsonnet-stdlib/src/std.jsonnetdiffbeforeafterboth
--- a/crates/jrsonnet-stdlib/src/std.jsonnet
+++ b/crates/jrsonnet-stdlib/src/std.jsonnet
@@ -477,19 +477,6 @@
     } else
       a,
 
-  findSubstr(pat, str)::
-    if !std.isString(pat) then
-      error 'findSubstr first parameter should be a string, got ' + std.type(pat)
-    else if !std.isString(str) then
-      error 'findSubstr second parameter should be a string, got ' + std.type(str)
-    else
-      local pat_len = std.length(pat);
-      local str_len = std.length(str);
-      if pat_len == 0 || str_len == 0 || pat_len > str_len then
-        []
-      else
-        std.filter(function(i) str[i:i + pat_len] == pat, std.range(0, str_len - pat_len)),
-
   find(value, arr)::
     if !std.isArray(arr) then
       error 'find second parameter should be an array, got ' + std.type(arr)