From b53c7c86572e05c756207ff9e2d848ce2cd1dcaa Mon Sep 17 00:00:00 2001 From: molsonkiko <46202915+molsonkiko@users.noreply.github.com> Date: Sat, 25 Nov 2023 23:21:43 -0800 Subject: [PATCH] improve s_sub, s_fa, s_csv performance previously s_fa and s_sub had unnecessarily bad performance because the TransformRegex function would be called every time each of those functions was invoked, but of course the regex only needs to be transformed once at compile time the new ArgsTransform class is a helper for other similar issues --- JsonToolsNppPlugin/JSONTools/RemesPath.cs | 1 + .../JSONTools/RemesPathFunctions.cs | 80 ++++++++++++------ JsonToolsNppPlugin/Properties/AssemblyInfo.cs | 4 +- most recent errors.txt | 82 +++++++++---------- 4 files changed, 97 insertions(+), 70 deletions(-) diff --git a/JsonToolsNppPlugin/JSONTools/RemesPath.cs b/JsonToolsNppPlugin/JSONTools/RemesPath.cs index 3616317..c705568 100644 --- a/JsonToolsNppPlugin/JSONTools/RemesPath.cs +++ b/JsonToolsNppPlugin/JSONTools/RemesPath.cs @@ -907,6 +907,7 @@ private JNode ApplyArgFunction(ArgFunctionWithArgs func) return new CurJson(func.function.type, blah => func.function.Call(func.args)); return func.function.Call(func.args); } + func.function.argsTransform?.Transform(func.args); JNode x = func.args[0]; bool other_callables = false; List other_args = new List(func.args.Count - 1); diff --git a/JsonToolsNppPlugin/JSONTools/RemesPathFunctions.cs b/JsonToolsNppPlugin/JSONTools/RemesPathFunctions.cs index cac3574..0e6352f 100644 --- a/JsonToolsNppPlugin/JSONTools/RemesPathFunctions.cs +++ b/JsonToolsNppPlugin/JSONTools/RemesPathFunctions.cs @@ -969,6 +969,10 @@ public class ArgFunction /// if false, the function is random /// public bool isDeterministic; + /// + /// transforms arguments at compile time + /// + public ArgsTransform argsTransform; /// /// A function whose arguments must be given in parentheses (e.g., len(x), concat(x, y), s_mul(abc, 3).

@@ -983,7 +987,8 @@ public ArgFunction(Func, JNode> function, int maxArgs, bool isVectorized, Dtype[] inputTypes, - bool isDeterministic = true) + bool isDeterministic = true, + ArgsTransform argsTransform = null) { Function = function; this.name = name; @@ -993,6 +998,7 @@ public ArgFunction(Func, JNode> function, this.isVectorized = isVectorized; this.inputTypes = inputTypes; this.isDeterministic = isDeterministic; + this.argsTransform = argsTransform; } /// @@ -2408,7 +2414,7 @@ public static string CsvRowRegex(int nColumns, char delimiter=',', string newlin /// /// /// - public static Regex TransformRegex(JNode regexOrString) + public static JRegex TransformRegex(JNode regexOrString) { string pat = regexOrString is JRegex jregex ? jregex.regex.ToString() : (string)regexOrString.value; string fixedPat = Regex.Replace(pat, @"(? @@ -2418,7 +2424,7 @@ public static Regex TransformRegex(JNode regexOrString) return mtch[3] == 'I' ? NONCAPTURING_INT_REGEX_STR : NONCAPTURING_FLOAT_REGEX_STR; return mtch[1] == 'I' ? CAPTURED_INT_REGEX_STR : CAPTURED_FLOAT_REGEX_STR; }); - return new Regex(fixedPat, RegexOptions.Compiled | RegexOptions.Multiline); + return new JRegex(new Regex(fixedPat, RegexOptions.Compiled | RegexOptions.Multiline)); } /// @@ -2435,7 +2441,7 @@ public static Regex TransformRegex(JNode regexOrString) /// number of columns (only used for s_csv) /// /// - public static JNode StrFindAllHelper(string text, JNode regexOrString, List args, int firstOptionalArgNum, string funcName, int nColumns=-1) + public static JNode StrFindAllHelper(string text, Regex rex, List args, int firstOptionalArgNum, string funcName, int nColumns=-1) { var columnNumbersToParseAsNumber = args.LazySlice($"{firstOptionalArgNum}:").Select(x => { @@ -2447,7 +2453,6 @@ public static JNode StrFindAllHelper(string text, JNode regexOrString, List(); - Regex rex = TransformRegex(regexOrString); Array.Sort(columnNumbersToParseAsNumber); int nextMatchStart = 0; var rows = new List(); @@ -2519,21 +2524,11 @@ public static JNode CsvRead(List args) if (args[1].type != Dtype.INT) throw new RemesPathArgumentException("second arg (nColumns) to s_csv must be integer", 1, FUNCTIONS["s_csv"]); int nColumns = Convert.ToInt32(args[1].value); - char delim = ','; - string newline = "\r\n"; - char quote = '"'; - if (args.Count > 2) - { - delim = args[2].type == Dtype.NULL ? ',' : ((string)args[2].value)[0]; - if (args.Count > 3) - { - newline = args[3].type == Dtype.NULL ? "\r\n" : (string)args[3].value; - if (args.Count > 4) - quote = args[4].type == Dtype.NULL ? '"' : ((string)args[4].value)[0]; - } - } + char delim = args.Count > 2 ? ((string)args[2].value)[0] : ','; + string newline = args.Count > 3 ? (string)args[3].value : "\r\n"; + char quote = args.Count > 4 ? ((string)args[4].value)[0] : '"'; string rexPat = CsvRowRegex(nColumns, delim, newline, quote); - return StrFindAllHelper(text, new JNode(rexPat), args, 5, "s_csv", nColumns); + return StrFindAllHelper(text, new Regex(rexPat, RegexOptions.Compiled), args, 5, "s_csv", nColumns); } /// @@ -2547,8 +2542,8 @@ public static JNode CsvRead(List args) public static JNode StrFindAll(List args) { string text = (string)args[0].value; - JNode rexNode = args[1]; - return StrFindAllHelper(text, rexNode, args, 2, "s_fa"); + Regex rex = ((JRegex)args[1]).regex; + return StrFindAllHelper(text, rex, args, 2, "s_fa"); } public static JNode StrSplit(List args) @@ -2607,11 +2602,11 @@ public static JNode StrSlice(List args) /// Returns:

/// * if toReplace is a string, a new string with all instances of toReplace in s replaced with repl

/// * if toReplace is a regex and repl is a string, uses .NET regex-replacement syntax (see https://learn.microsoft.com/en-us/dotnet/standard/base-types/regular-expression-language-quick-reference#substitutions)

- /// * if toReplace is a regex and repl is a function, returns a

+ /// * if toReplace is a regex and repl is a function (must take an array as input and return a string), returns that function applied to the "match array" for each regex match. The "match array" always has the captured string as its first element and the n^th capture group as its (n+1)^th element. You can access the number of matches made so far within the callback using the loop() function.

/// EXAMPLES:

/// * s_sub(abbbbc, g`b+`, z) -> "azc"

/// * s_sub(`123 123`, `1`, `z`) -> "z23 z23"

- /// * s_sub(g`a b c`, g`[a-z]`, @[0]*loop()) + /// * s_sub(`1a 2b 3c`, g`(\d)([a-z])`, (@[2]*loop()) + @[1]) -> "a1 bb2 ccc3" (the callback function (arg 3) returns any instance of a digit, then a letter letter with (that letter * (the number of matches made so far + 1), followed by the digit)

/// NOTE: prior to JsonTools 4.10.1, it didn't matter whether arg 2 was a string or regex; it always treated it as a regex. ///
/// new JNode of type = Dtype.STR with all replacements made @@ -2623,7 +2618,7 @@ public static JNode StrSub(List args) string replStr; if (toReplace is JRegex jRegex) { - Regex regex = TransformRegex(jRegex); + Regex regex = jRegex.regex; if (repl is CurJson cj) { Func fun = cj.function; @@ -2958,8 +2953,8 @@ public static JNode ObjectsToJNode(object obj) ["parse"] = new ArgFunction(Parse, "parse", Dtype.OBJ, 1, 1, true, new Dtype[] { Dtype.STR | Dtype.ITERABLE }), ["round"] = new ArgFunction(Round, "round", Dtype.FLOAT_OR_INT, 1, 2, true, new Dtype[] {Dtype.FLOAT_OR_INT | Dtype.ITERABLE, Dtype.INT}), ["s_count"] = new ArgFunction(StrCount, "s_count", Dtype.INT, 2, 2, true, new Dtype[] {Dtype.STR | Dtype.ITERABLE, Dtype.STR_OR_REGEX}), - ["s_csv"] = new ArgFunction(CsvRead, "s_csv", Dtype.ARR, 2, int.MaxValue, true, new Dtype[] {Dtype.STR | Dtype.ITERABLE, Dtype.INT, Dtype.STR | Dtype.NULL, Dtype.STR | Dtype.NULL, Dtype.STR | Dtype.NULL, Dtype.INT}), - ["s_fa"] = new ArgFunction(StrFindAll, "s_fa", Dtype.ARR, 2, int.MaxValue, true, new Dtype[] {Dtype.STR | Dtype.ITERABLE, Dtype.STR_OR_REGEX, Dtype.INT}), + ["s_csv"] = new ArgFunction(CsvRead, "s_csv", Dtype.ARR, 2, int.MaxValue, true, new Dtype[] {Dtype.STR | Dtype.ITERABLE, Dtype.INT, Dtype.STR | Dtype.NULL, Dtype.STR | Dtype.NULL, Dtype.STR | Dtype.NULL, Dtype.INT}, true, new ArgsTransform((2, Dtype.NULL, x => new JNode(",")), (3, Dtype.NULL, x => new JNode("\r\n")), (4, Dtype.NULL, x => new JNode("\"")))), + ["s_fa"] = new ArgFunction(StrFindAll, "s_fa", Dtype.ARR, 2, int.MaxValue, true, new Dtype[] {Dtype.STR | Dtype.ITERABLE, Dtype.STR_OR_REGEX, Dtype.INT}, true, new ArgsTransform((1, Dtype.STR_OR_REGEX, TransformRegex))), ["s_find"] = new ArgFunction(StrFind, "s_find", Dtype.ARR, 2, 2, true, new Dtype[] {Dtype.STR | Dtype.ITERABLE, Dtype.REGEX}), ["s_len"] = new ArgFunction(StrLen, "s_len", Dtype.INT, 1, 1, true, new Dtype[] {Dtype.STR | Dtype.ITERABLE}), ["s_lower"] = new ArgFunction(StrLower, "s_lower", Dtype.STR, 1, 1, true, new Dtype[] {Dtype.STR | Dtype.ITERABLE}), @@ -2967,7 +2962,7 @@ public static JNode ObjectsToJNode(object obj) ["s_slice"] = new ArgFunction(StrSlice, "s_slice", Dtype.STR, 2, 2, true, new Dtype[] {Dtype.STR | Dtype.ITERABLE, Dtype.INT_OR_SLICE}), ["s_split"] = new ArgFunction(StrSplit, "s_split", Dtype.ARR, 1, 2, true, new Dtype[] {Dtype.STR | Dtype.ITERABLE, Dtype.STR_OR_REGEX}), ["s_strip"] = new ArgFunction(StrStrip, "s_strip", Dtype.STR, 1, 1, true, new Dtype[] {Dtype.STR | Dtype.ITERABLE}), - ["s_sub"] = new ArgFunction(StrSub, "s_sub", Dtype.STR, 3, 3, true, new Dtype[] {Dtype.STR | Dtype.ITERABLE, Dtype.STR_OR_REGEX, Dtype.STR | Dtype.FUNCTION}), + ["s_sub"] = new ArgFunction(StrSub, "s_sub", Dtype.STR, 3, 3, true, new Dtype[] {Dtype.STR | Dtype.ITERABLE, Dtype.STR_OR_REGEX, Dtype.STR | Dtype.FUNCTION}, true, new ArgsTransform((1, Dtype.REGEX, TransformRegex))), ["s_upper"] = new ArgFunction(StrUpper, "s_upper", Dtype.STR, 1, 1, true, new Dtype[] {Dtype.STR | Dtype.ITERABLE}), ["str"] = new ArgFunction(ToStr, "str", Dtype.STR, 1, 1, true, new Dtype[] {Dtype.ANYTHING}) }; @@ -2990,4 +2985,35 @@ public JNode Call() return function.Call(args); } } + + /// + /// used to transform the args of an ArgFunction at compile time, before the function is ever called.

+ /// this may be useful for replacing null optional args with their default value, or performing expensive transformations

+ /// like the "(INT)" -> (integer-matching regex) transformation of regexes for s_sub and s_fa. + ///
+ public class ArgsTransform + { + private (int index, Dtype typesToTransform, Func tranformer)[] transformers; + + public ArgsTransform(params (int index, Dtype typesToTransform, Func transformer)[] args) + { + transformers = args; + } + + /// + /// if args[Index] has a type in TypesToTransform, replace args[Index] with Transformer(args[Index]) + /// + public void Transform(List args) + { + foreach ((int index, Dtype typesToTransform, Func transformer) in transformers) + { + if (args.Count > index) + { + var arg = args[index]; + if ((arg.type & typesToTransform) != 0) + args[index] = transformer(arg); + } + } + } + } } \ No newline at end of file diff --git a/JsonToolsNppPlugin/Properties/AssemblyInfo.cs b/JsonToolsNppPlugin/Properties/AssemblyInfo.cs index ef27948..957b601 100644 --- a/JsonToolsNppPlugin/Properties/AssemblyInfo.cs +++ b/JsonToolsNppPlugin/Properties/AssemblyInfo.cs @@ -29,5 +29,5 @@ // Build Number // Revision // -[assembly: AssemblyVersion("5.8.0.8")] -[assembly: AssemblyFileVersion("5.8.0.8")] +[assembly: AssemblyVersion("5.8.0.9")] +[assembly: AssemblyFileVersion("5.8.0.9")] diff --git a/most recent errors.txt b/most recent errors.txt index 39c7f69..554d844 100644 --- a/most recent errors.txt +++ b/most recent errors.txt @@ -1,4 +1,4 @@ -Test results for JsonTools v5.8.0.8 on Notepad++ 8.5.8 64bit +Test results for JsonTools v5.8.0.9 on Notepad++ 8.5.8 64bit NOTE: Ctrl-F (regular expressions *on*) for "Failed [1-9]\d*" to find all failed tests Tests failed: YAML dumper ========================= @@ -202,33 +202,33 @@ Testing JsonParser performance Preview of json: [{"A": "Ky'c^g#~)0", "a": 1850111954, "b": 9318359041, "B": "Oyi:/ xxe2", "C": "sKCSa_^7Gg", "c": 7974777124, "d": 2670309238, "D": "0d_K)HmX!.", "E": ".uM*Z{0EJ_", "e": 6958410336, "f": 8050244728, "F": "1%SG_A!xB\t", "g": 3799657125, "G": "il1^k\\\nat*", "H": {"a": 6079042826, "b": 7292804611, "c" ... -To convert JSON string of size 89556 into JNode took 2.819 +/- 1.619 ms over 32 trials -Load times (ms): 1, 1, 3, 9, 2, 2, 5, 5, 2, 3, 3, 3, 1, 1, 4, 1, 1, 1, 2, 1, 1, 4, 1, 1, 1, 2, 1, 2, 4, 1, 1, 1 +To convert JSON string of size 89556 into JNode took 3.349 +/- 3.039 ms over 32 trials +Load times (ms): 2, 3, 1, 1, 1, 18, 2, 2, 4, 2, 2, 2, 2, 1, 1, 5, 2, 2, 2, 3, 2, 2, 5, 2, 2, 2, 3, 2, 2, 7, 2, 2 ========================= Performance tests for RemesPath (float arithmetic) ========================= -Compiling query "@[@[:].a * @[:].t < @[:].e]" into took 3.508 +/- 21.488 microseconds over 40 trials -To run pre-compiled query "@[@[:].a * @[:].t < @[:].e]" on JNode from JSON of size 89556 into took 0.024 +/- 0.005 ms over 40 trials -Query times (ms): 0.054, 0.03, 0.023, 0.023, 0.023, 0.023, 0.023, 0.025, 0.023, 0.024, 0.023, 0.022, 0.022, 0.025, 0.023, 0.023, 0.023, 0.024, 0.022, 0.024, 0.024, 0.023, 0.024, 0.022, 0.023, 0.025, 0.023, 0.023, 0.024, 0.023, 0.022, 0.024, 0.024, 0.023, 0.023, 0.022, 0.023, 0.024, 0.023, 0.024 +Compiling query "@[@[:].a * @[:].t < @[:].e]" into took 4.04 +/- 24.589 microseconds over 40 trials +To run pre-compiled query "@[@[:].a * @[:].t < @[:].e]" on JNode from JSON of size 89556 into took 0.117 +/- 0.455 ms over 40 trials +Query times (ms): 0.138, 0.065, 0.047, 0.042, 0.034, 0.032, 0.041, 0.039, 0.033, 0.034, 0.034, 0.031, 0.034, 0.047, 0.036, 0.036, 0.03, 0.044, 0.03, 0.068, 0.053, 0.06, 0.06, 0.052, 0.052, 0.073, 0.055, 0.05, 0.056, 0.051, 2.958, 0.03, 0.023, 0.024, 0.024, 0.022, 0.024, 0.045, 0.04, 0.035 Preview of result: [{"A": "Ky'c^g#~)0", "a": 1850111954, "b": 9318359041, "B": "Oyi:/ xxe2", "C": "sKCSa_^7Gg", "c": 7974777124, "d": 2670309238, "D": "0d_K)HmX!.", "E": ".uM*Z{0EJ_", "e": 6958410336, "f": 8050244728, "F": "1%SG_A!xB\t", "g": 3799657125, "G": "il1^k\\\nat*", "H": {"a": 6079042826, "b": 7292804611, "c" ... ========================= Performance tests for RemesPath (string operations) ========================= -Compiling query "@[@[:].z =~ `(?i)[a-z]{5}`]" into took 2.558 +/- 15.283 microseconds over 40 trials -To run pre-compiled query "@[@[:].z =~ `(?i)[a-z]{5}`]" on JNode from JSON of size 89556 into took 0.104 +/- 0.012 ms over 40 trials -Query times (ms): 0.18, 0.105, 0.103, 0.102, 0.101, 0.101, 0.1, 0.102, 0.108, 0.102, 0.101, 0.102, 0.102, 0.102, 0.103, 0.101, 0.106, 0.101, 0.101, 0.102, 0.101, 0.101, 0.101, 0.102, 0.101, 0.106, 0.101, 0.102, 0.102, 0.103, 0.102, 0.105, 0.103, 0.102, 0.105, 0.102, 0.103, 0.106, 0.102, 0.101 +Compiling query "@[@[:].z =~ `(?i)[a-z]{5}`]" into took 2.402 +/- 14.395 microseconds over 40 trials +To run pre-compiled query "@[@[:].z =~ `(?i)[a-z]{5}`]" on JNode from JSON of size 89556 into took 0.069 +/- 0.023 ms over 40 trials +Query times (ms): 0.15, 0.098, 0.094, 0.088, 0.101, 0.099, 0.098, 0.057, 0.053, 0.053, 0.055, 0.087, 0.092, 0.099, 0.09, 0.09, 0.096, 0.093, 0.059, 0.055, 0.052, 0.052, 0.053, 0.052, 0.052, 0.055, 0.052, 0.053, 0.052, 0.052, 0.052, 0.054, 0.052, 0.053, 0.053, 0.054, 0.053, 0.055, 0.054, 0.052 Preview of result: [{"A": "\n]o1VQ5t6g", "a": 4710024278, "b": 3268860721, "B": "g4Y7+ew^.v", "C": "NK nmax_notq, `when q=true, nmax = ` + str(nmax_q), `when q=false, nmax= ` + str(nmax_notq))" into took 8.78 +/- 53.182 microseconds over 40 trials +ifelse(nmax_q > nmax_notq, `when q=true, nmax = ` + str(nmax_q), `when q=false, nmax= ` + str(nmax_notq))" into took 6.745 +/- 40.665 microseconds over 40 trials To run pre-compiled query "var qmask = @[:].q; var nmax_q = max(@[qmask].n); var nmax_notq = max(@[not qmask].n); -ifelse(nmax_q > nmax_notq, `when q=true, nmax = ` + str(nmax_q), `when q=false, nmax= ` + str(nmax_notq))" on JNode from JSON of size 89556 into took 0.04 +/- 0.045 ms over 40 trials -Query times (ms): 0.099, 0.037, 0.03, 0.035, 0.031, 0.053, 0.029, 0.03, 0.03, 0.31, 0.036, 0.029, 0.029, 0.036, 0.031, 0.029, 0.029, 0.03, 0.029, 0.029, 0.03, 0.029, 0.029, 0.029, 0.03, 0.029, 0.029, 0.03, 0.029, 0.03, 0.03, 0.029, 0.029, 0.03, 0.03, 0.029, 0.029, 0.031, 0.029, 0.03 +ifelse(nmax_q > nmax_notq, `when q=true, nmax = ` + str(nmax_q), `when q=false, nmax= ` + str(nmax_notq))" on JNode from JSON of size 89556 into took 0.034 +/- 0.044 ms over 40 trials +Query times (ms): 0.098, 0.031, 0.038, 0.024, 0.047, 0.023, 0.024, 0.025, 0.023, 0.024, 0.024, 0.025, 0.025, 0.025, 0.026, 0.024, 0.024, 0.025, 0.295, 0.032, 0.024, 0.023, 0.023, 0.024, 0.023, 0.023, 0.024, 0.023, 0.023, 0.024, 0.023, 0.023, 0.024, 0.031, 0.023, 0.023, 0.023, 0.024, 0.024, 0.027 Preview of result: "when q=false, nmax= 9830935647.0" ... ========================= @@ -267,11 +267,11 @@ Performance tests for RemesPath (references to compile-time constant variables) Compiling query "var X = X; var onetwo = j`[1, 2]`; -@[:]->at(@, X)->at(@, onetwo)" into took 3.138 +/- 19.001 microseconds over 40 trials +@[:]->at(@, X)->at(@, onetwo)" into took 3.97 +/- 24.008 microseconds over 40 trials To run pre-compiled query "var X = X; var onetwo = j`[1, 2]`; -@[:]->at(@, X)->at(@, onetwo)" on JNode from JSON of size 89556 into took 0.015 +/- 0.009 ms over 40 trials -Query times (ms): 0.058, 0.013, 0.012, 0.013, 0.02, 0.014, 0.013, 0.013, 0.033, 0.012, 0.012, 0.012, 0.037, 0.012, 0.012, 0.012, 0.012, 0.012, 0.012, 0.013, 0.012, 0.012, 0.012, 0.012, 0.012, 0.012, 0.013, 0.012, 0.012, 0.012, 0.012, 0.012, 0.013, 0.012, 0.012, 0.012, 0.012, 0.012, 0.012, 0.017 +@[:]->at(@, X)->at(@, onetwo)" on JNode from JSON of size 89556 into took 0.029 +/- 0.027 ms over 40 trials +Query times (ms): 0.072, 0.025, 0.021, 0.023, 0.036, 0.022, 0.049, 0.021, 0.021, 0.021, 0.021, 0.022, 0.022, 0.022, 0.021, 0.021, 0.023, 0.025, 0.023, 0.023, 0.022, 0.022, 0.023, 0.023, 0.023, 0.022, 0.021, 0.022, 0.021, 0.022, 0.022, 0.022, 0.19, 0.032, 0.025, 0.024, 0.025, 0.025, 0.024, 0.025 Preview of result: [[1695727848, 0.287562638736685], [2126430375, 0.00767794129708177], [5310550656, 0.380769772645687], [2519183283, 0.153176220930558], [6610062385, 0.662996225870666], [987168256, 0.924410189999928], [6615003609, 0.917112691225947], [4465232046, 0.684311931851536], [8654414565, 0.631485392105992], [ ... ========================= @@ -280,29 +280,29 @@ Performance tests for RemesPath (references to variables that are not compile-ti Compiling query "var X = @->`X`; var onetwo = @{1, 2}; -@[:]->at(@, X)->at(@, onetwo)" into took 3.395 +/- 20.577 microseconds over 40 trials +@[:]->at(@, X)->at(@, onetwo)" into took 4.7 +/- 28.311 microseconds over 40 trials To run pre-compiled query "var X = @->`X`; var onetwo = @{1, 2}; -@[:]->at(@, X)->at(@, onetwo)" on JNode from JSON of size 89556 into took 0.018 +/- 0.009 ms over 40 trials -Query times (ms): 0.065, 0.017, 0.017, 0.017, 0.017, 0.016, 0.023, 0.03, 0.016, 0.044, 0.017, 0.016, 0.015, 0.016, 0.016, 0.016, 0.016, 0.016, 0.016, 0.016, 0.016, 0.016, 0.016, 0.016, 0.015, 0.016, 0.016, 0.015, 0.016, 0.016, 0.016, 0.016, 0.016, 0.016, 0.016, 0.016, 0.016, 0.016, 0.016, 0.015 +@[:]->at(@, X)->at(@, onetwo)" on JNode from JSON of size 89556 into took 0.036 +/- 0.021 ms over 40 trials +Query times (ms): 0.088, 0.037, 0.026, 0.054, 0.029, 0.057, 0.027, 0.027, 0.146, 0.041, 0.028, 0.035, 0.026, 0.028, 0.025, 0.027, 0.038, 0.055, 0.026, 0.026, 0.026, 0.026, 0.026, 0.026, 0.025, 0.026, 0.026, 0.026, 0.027, 0.028, 0.03, 0.032, 0.031, 0.033, 0.033, 0.033, 0.033, 0.034, 0.033, 0.027 Preview of result: [[1695727848, 0.287562638736685], [2126430375, 0.00767794129708177], [5310550656, 0.380769772645687], [2519183283, 0.153176220930558], [6610062385, 0.662996225870666], [987168256, 0.924410189999928], [6615003609, 0.917112691225947], [4465232046, 0.684311931851536], [8654414565, 0.631485392105992], [ ... ========================= Performance tests for RemesPath (simple string mutations) ========================= -Compiling query "@[:].z = s_sub(@, g, B)" into took 3.128 +/- 18.875 microseconds over 40 trials -To run pre-compiled query "@[:].z = s_sub(@, g, B)" on JNode from JSON of size 89556 into took 0.014 +/- 0.005 ms over 40 trials -Query times (ms): 0.036, 0.024, 0.012, 0.012, 0.01, 0.013, 0.014, 0.013, 0.014, 0.016, 0.027, 0.015, 0.011, 0.01, 0.01, 0.012, 0.011, 0.009, 0.013, 0.022, 0.014, 0.015, 0.018, 0.015, 0.016, 0.021, 0.012, 0.013, 0.011, 0.012, 0.011, 0.011, 0.01, 0.011, 0.01, 0.012, 0.014, 0.018, 0.012, 0.011 +Compiling query "@[:].z = s_sub(@, g, B)" into took 2.878 +/- 17.297 microseconds over 40 trials +To run pre-compiled query "@[:].z = s_sub(@, g, B)" on JNode from JSON of size 89556 into took 0.034 +/- 0.041 ms over 40 trials +Query times (ms): 0.025, 0.012, 0.012, 0.017, 0.01, 0.011, 0.038, 0.038, 0.037, 0.03, 0.031, 0.028, 0.026, 0.043, 0.04, 0.046, 0.044, 0.028, 0.026, 0.026, 0.019, 0.019, 0.018, 0.285, 0.022, 0.031, 0.037, 0.028, 0.039, 0.021, 0.024, 0.036, 0.029, 0.025, 0.029, 0.027, 0.025, 0.03, 0.028, 0.022 Preview of result: [{"A": "Ky'c^g#~)0", "a": 1850111954, "b": 9318359041, "B": "Oyi:/ xxe2", "C": "sKCSa_^7Gg", "c": 7974777124, "d": 2670309238, "D": "0d_K)HmX!.", "E": ".uM*Z{0EJ_", "e": 6958410336, "f": 8050244728, "F": "1%SG_A!xB\t", "g": 3799657125, "G": "il1^k\\\nat*", "H": {"a": 6079042826, "b": 7292804611, "c" ... ========================= Performance tests for RemesPath (simple number mutations) ========================= -Compiling query "@[:].x = ifelse(@ < 0.5, @ + 3, @ - 3)" into took 4.688 +/- 28.489 microseconds over 40 trials -To run pre-compiled query "@[:].x = ifelse(@ < 0.5, @ + 3, @ - 3)" on JNode from JSON of size 89556 into took 0.042 +/- 0.031 ms over 40 trials -Query times (ms): 0.052, 0.03, 0.023, 0.021, 0.022, 0.028, 0.027, 0.031, 0.07, 0.04, 0.036, 0.034, 0.038, 0.038, 0.046, 0.07, 0.043, 0.219, 0.022, 0.055, 0.049, 0.05, 0.044, 0.043, 0.042, 0.026, 0.023, 0.023, 0.021, 0.021, 0.021, 0.022, 0.027, 0.051, 0.062, 0.048, 0.043, 0.049, 0.041, 0.041 +Compiling query "@[:].x = ifelse(@ < 0.5, @ + 3, @ - 3)" into took 4.585 +/- 28.041 microseconds over 40 trials +To run pre-compiled query "@[:].x = ifelse(@ < 0.5, @ + 3, @ - 3)" on JNode from JSON of size 89556 into took 0.042 +/- 0.014 ms over 40 trials +Query times (ms): 0.066, 0.056, 0.047, 0.046, 0.043, 0.044, 0.041, 0.082, 0.069, 0.034, 0.047, 0.063, 0.057, 0.05, 0.039, 0.04, 0.038, 0.039, 0.038, 0.038, 0.038, 0.04, 0.038, 0.046, 0.048, 0.055, 0.023, 0.022, 0.021, 0.021, 0.037, 0.037, 0.032, 0.021, 0.033, 0.023, 0.029, 0.064, 0.046, 0.025 Preview of result: [{"A": "Ky'c^g#~)0", "a": 1850111954, "b": 9318359041, "B": "Oyi:/ xxe2", "C": "sKCSa_^7Gg", "c": 7974777124, "d": 2670309238, "D": "0d_K)HmX!.", "E": ".uM*Z{0EJ_", "e": 6958410336, "f": 8050244728, "F": "1%SG_A!xB\t", "g": 3799657125, "G": "il1^k\\\nat*", "H": {"a": 6079042826, "b": 7292804611, "c" ... ========================= @@ -312,12 +312,12 @@ Performance tests for RemesPath (mutations with a for loop) Compiling query "var xhalf = @[:].x < 0.5; for lx = zip(@[:].l, xhalf); lx[0] = ifelse(lx[1], foo, bar); -end for;" into took 7.572 +/- 46.121 microseconds over 40 trials +end for;" into took 6.492 +/- 39.521 microseconds over 40 trials To run pre-compiled query "var xhalf = @[:].x < 0.5; for lx = zip(@[:].l, xhalf); lx[0] = ifelse(lx[1], foo, bar); -end for;" on JNode from JSON of size 89556 into took 0.086 +/- 0.213 ms over 40 trials -Query times (ms): 0.104, 0.084, 0.109, 0.068, 1.412, 0.086, 0.073, 0.108, 0.057, 0.063, 0.038, 0.038, 0.049, 0.039, 0.037, 0.037, 0.036, 0.049, 0.038, 0.038, 0.037, 0.037, 0.037, 0.038, 0.036, 0.038, 0.034, 0.036, 0.037, 0.066, 0.068, 0.044, 0.059, 0.06, 0.044, 0.037, 0.062, 0.038, 0.035, 0.036 +end for;" on JNode from JSON of size 89556 into took 0.073 +/- 0.038 ms over 40 trials +Query times (ms): 0.067, 0.043, 0.04, 0.038, 0.036, 0.039, 0.056, 0.049, 0.118, 0.065, 0.066, 0.063, 0.058, 0.058, 0.061, 0.063, 0.06, 0.059, 0.059, 0.062, 0.086, 0.087, 0.064, 0.06, 0.062, 0.075, 0.071, 0.058, 0.056, 0.086, 0.087, 0.098, 0.093, 0.098, 0.094, 0.085, 0.086, 0.079, 0.059, 0.284 Preview of result: [["bar", false], ["bar", false], ["foo", true], ["foo", true], ["foo", true], ["foo", true], ["foo", true], ["bar", false], ["bar", false], ["bar", false], ["foo", true], ["foo", true], ["bar", false], ["bar", false], ["foo", true], ["bar", false], ["bar", false], ["bar", false], ["foo", true], ["ba ... ========================= @@ -326,18 +326,18 @@ Testing performance of JSON compression and pretty-printing Preview of json: [{"A": "Ky'c^g#~)0", "a": 1850111954, "b": 9318359041, "B": "Oyi:/ xxe2", "C": "sKCSa_^7Gg", "c": 7974777124, "d": 2670309238, "D": "0d_K)HmX!.", "E": ".uM*Z{0EJ_", "e": 6958410336, "f": 8050244728, "F": "1%SG_A!xB\t", "g": 3799657125, "G": "il1^k\\\nat*", "H": {"a": 6079042826, "b": 7292804611, "c" ... -To compress JNode from JSON string of 89556 took 5.51 +/- 1.207 ms over 64 trials (minimal whitespace, sort_keys=TRUE) -To compress JNode from JSON string of 89556 took 3.709 +/- 2.118 ms over 64 trials (minimal whitespace, sort_keys=FALSE) -To Google-style pretty-print JNode from JSON string of 89556 took 5.12 +/- 1.238 ms over 64 trials (sort_keys=true, indent=4) -To Whitesmith-style pretty-print JNode from JSON string of 89556 took 5.773 +/- 1.475 ms over 64 trials (sort_keys=true, indent=4) -To PPrint-style pretty-print JNode from JSON string of 89556 took 7.715 +/- 1.85 ms over 64 trials (sort_keys=true, indent=4) +To compress JNode from JSON string of 89556 took 6.28 +/- 1.494 ms over 64 trials (minimal whitespace, sort_keys=TRUE) +To compress JNode from JSON string of 89556 took 2.76 +/- 0.678 ms over 64 trials (minimal whitespace, sort_keys=FALSE) +To Google-style pretty-print JNode from JSON string of 89556 took 5.342 +/- 1.313 ms over 64 trials (sort_keys=true, indent=4) +To Whitesmith-style pretty-print JNode from JSON string of 89556 took 5.872 +/- 1.449 ms over 64 trials (sort_keys=true, indent=4) +To PPrint-style pretty-print JNode from JSON string of 89556 took 7.528 +/- 1.905 ms over 64 trials (sort_keys=true, indent=4) ========================= Testing performance of JsonSchemaValidator and random JSON creation ========================= -To create a random set of tweet JSON of size 233408 (15 tweets) based on the matching schema took 7.875 +/- 3.738 ms over 64 trials -To compile the tweet schema to a validation function took 0.315 +/- 0.413 ms over 64 trials -To validate tweet JSON of size 233408 (15 tweets) based on the compiled schema took 1.346 +/- 0.407 ms over 64 trials +To create a random set of tweet JSON of size 184150 (15 tweets) based on the matching schema took 8.164 +/- 4.04 ms over 64 trials +To compile the tweet schema to a validation function took 0.273 +/- 0.08 ms over 64 trials +To validate tweet JSON of size 184150 (15 tweets) based on the compiled schema took 1.326 +/- 0.378 ms over 64 trials ========================= Testing JSON grepper's API request tool =========================