1- use jaq_json:: Val ;
2- use serde_json:: json;
31use criterion:: { criterion_group, criterion_main, Criterion } ;
4- use tailcall_template:: mustache:: { Mustache , Segment } ;
52use jaq_core:: { load, Ctx , Native , RcIter } ;
3+ use jaq_json:: Val ;
64use load:: { Arena , File , Loader } ;
5+ use serde_json:: json;
6+ use tailcall_template:: {
7+ self ,
8+ jq:: jq:: JsonLikeHelper ,
9+ mustache:: { Mustache , Segment } ,
10+ } ;
711
812criterion_group ! ( benches, criterion_benchmark) ;
913criterion_main ! ( benches) ;
@@ -18,10 +22,15 @@ pub fn criterion_benchmark(c: &mut Criterion) {
1822 Segment :: Literal ( "Value: " . to_string( ) ) ,
1923 Segment :: Expression ( vec![ "key" . to_string( ) ] ) ,
2024 ] ) ;
21- c. bench_function ( "basic_mustache" , |b| b. iter ( || bench_mustache ( & data, & mustache, & expected) ) ) ;
25+ c. bench_function ( "basic_mustache" , |b| {
26+ b. iter ( || bench_mustache ( & data, & mustache, & expected) )
27+ } ) ;
2228 }
2329 {
24- let program = File { code : "\" Value: \" + .key" , path : ( ) } ;
30+ let program = File {
31+ code : "\" Value: \" + .key" ,
32+ path : ( ) ,
33+ } ;
2534
2635 // start out only from core filters,
2736 // which do not include filters in the standard library
@@ -33,11 +42,39 @@ pub fn criterion_benchmark(c: &mut Criterion) {
3342 let modules = loader. load ( & arena, program) . unwrap ( ) ;
3443
3544 // compile the filter
36- let filter: jaq_core:: Filter < Native < Val > > = jaq_core:: Compiler :: < _ , Native < _ > > :: default ( )
37- . compile ( modules)
38- . unwrap ( ) ;
45+ let filter: jaq_core:: Filter < Native < Val > > =
46+ jaq_core:: Compiler :: < _ , Native < _ > > :: default ( )
47+ . compile ( modules)
48+ . unwrap ( ) ;
3949
40- c. bench_function ( "basic_jq" , |b| b. iter ( || bench_jq ( & data, & filter, & expected) ) ) ;
50+ c. bench_function ( "basic_jq" , |b| {
51+ b. iter ( || bench_jq ( & data, & filter, & expected) )
52+ } ) ;
53+ }
54+ {
55+ let program = File {
56+ code : "\" Value: \" + .key" ,
57+ path : ( ) ,
58+ } ;
59+
60+ // start out only from core filters,
61+ // which do not include filters in the standard library
62+ // such as `map`, `select` etc.
63+ let loader = Loader :: new ( [ ] ) ;
64+ let arena = Arena :: default ( ) ;
65+
66+ // parse the filter
67+ let modules = loader. load ( & arena, program) . unwrap ( ) ;
68+
69+ // compile the filter
70+ let filter: jaq_core:: Filter < Native < JsonLikeHelper < serde_json:: Value > > > =
71+ jaq_core:: Compiler :: < _ , Native < _ > > :: default ( )
72+ . compile ( modules)
73+ . unwrap ( ) ;
74+
75+ c. bench_function ( "basic_jsonlike" , |b| {
76+ b. iter ( || bench_jsonlike ( & data, & filter, & expected) )
77+ } ) ;
4178 }
4279 }
4380 // COMPLEX SCENARIO
@@ -51,19 +88,44 @@ pub fn criterion_benchmark(c: &mut Criterion) {
5188 Segment :: Literal ( ", Age: " . to_string( ) ) ,
5289 Segment :: Expression ( vec![ "age" . to_string( ) ] ) ,
5390 ] ) ;
54- c. bench_function ( "complex_mustache" , |b| b. iter ( || bench_mustache ( & data, & mustache, & expected) ) ) ;
91+ c. bench_function ( "complex_mustache" , |b| {
92+ b. iter ( || bench_mustache ( & data, & mustache, & expected) )
93+ } ) ;
5594 }
5695 {
57- let program = File { code : "\" User: \" + .user + \" , Age: \" + (.age | tostring)" , path : ( ) } ;
58- let loader = Loader :: new ( jaq_std:: defs ( ) ) ;
96+ let program = File {
97+ code : "\" User: \" + .user + \" , Age: \" + (.age | tostring)" ,
98+ path : ( ) ,
99+ } ;
100+ let defs = jaq_core:: load:: parse ( "def tostring: \" \\ (.)\" ;" , |p| p. defs ( ) ) . unwrap ( ) ;
101+ let loader = Loader :: new ( defs) ;
59102 let arena = Arena :: default ( ) ;
60103 let modules = loader. load ( & arena, program) . unwrap ( ) ;
61104 let filter = jaq_core:: Compiler :: < _ , Native < _ > > :: default ( )
62- . with_funs ( jaq_std:: funs ( ) )
63105 . compile ( modules)
64106 . unwrap ( ) ;
65107
66- c. bench_function ( "complex_jq" , |b| b. iter ( || bench_jq ( & data, & filter, & expected) ) ) ;
108+ c. bench_function ( "complex_jq" , |b| {
109+ b. iter ( || bench_jq ( & data, & filter, & expected) )
110+ } ) ;
111+ }
112+ {
113+ let program = File {
114+ code : "\" User: \" + .user + \" , Age: \" + (.age | tostring)" ,
115+ path : ( ) ,
116+ } ;
117+
118+ let defs = jaq_core:: load:: parse ( "def tostring: \" \\ (.)\" ;" , |p| p. defs ( ) ) . unwrap ( ) ;
119+ let loader = Loader :: new ( defs) ;
120+ let arena = Arena :: default ( ) ;
121+ let modules = loader. load ( & arena, program) . unwrap ( ) ;
122+ let filter = jaq_core:: Compiler :: < _ , Native < _ > > :: default ( )
123+ . compile ( modules)
124+ . unwrap ( ) ;
125+
126+ c. bench_function ( "complex_jsonlike" , |b| {
127+ b. iter ( || bench_jsonlike ( & data, & filter, & expected) )
128+ } ) ;
67129 }
68130 }
69131 // NESTED SCENARIO
@@ -86,25 +148,57 @@ pub fn criterion_benchmark(c: &mut Criterion) {
86148 Segment :: Literal ( "User: " . to_string( ) ) ,
87149 Segment :: Expression ( vec![ "user" . to_string( ) , "name" . to_string( ) ] ) ,
88150 Segment :: Literal ( ", Age: " . to_string( ) ) ,
89- Segment :: Expression ( vec![ "user" . to_string( ) , "details" . to_string( ) , "age" . to_string( ) ] ) ,
151+ Segment :: Expression ( vec![
152+ "user" . to_string( ) ,
153+ "details" . to_string( ) ,
154+ "age" . to_string( ) ,
155+ ] ) ,
90156 Segment :: Literal ( ", Location: " . to_string( ) ) ,
91- Segment :: Expression ( vec![ "user" . to_string( ) , "details" . to_string( ) , "location" . to_string( ) , "city" . to_string( ) ] ) ,
157+ Segment :: Expression ( vec![
158+ "user" . to_string( ) ,
159+ "details" . to_string( ) ,
160+ "location" . to_string( ) ,
161+ "city" . to_string( ) ,
162+ ] ) ,
92163 Segment :: Literal ( ", Country: " . to_string( ) ) ,
93- Segment :: Expression ( vec![ "user" . to_string( ) , "details" . to_string( ) , "location" . to_string( ) , "country" . to_string( ) ] ) ,
164+ Segment :: Expression ( vec![
165+ "user" . to_string( ) ,
166+ "details" . to_string( ) ,
167+ "location" . to_string( ) ,
168+ "country" . to_string( ) ,
169+ ] ) ,
94170 ] ) ;
95- c. bench_function ( "nested_mustache" , |b| b. iter ( || bench_mustache ( & data, & mustache, & expected) ) ) ;
171+ c. bench_function ( "nested_mustache" , |b| {
172+ b. iter ( || bench_mustache ( & data, & mustache, & expected) )
173+ } ) ;
174+ }
175+ {
176+ let program = File { code : "\" User: \" + .user.name + \" , Age: \" + (.user.details.age | tostring) + \" , Location: \" + .user.details.location.city + \" , Country: \" + .user.details.location.country" , path : ( ) } ;
177+ let defs = jaq_core:: load:: parse ( "def tostring: \" \\ (.)\" ;" , |p| p. defs ( ) ) . unwrap ( ) ;
178+ let loader = Loader :: new ( defs) ;
179+ let arena = Arena :: default ( ) ;
180+ let modules = loader. load ( & arena, program) . unwrap ( ) ;
181+ let filter = jaq_core:: Compiler :: < _ , Native < _ > > :: default ( )
182+ . compile ( modules)
183+ . unwrap ( ) ;
184+
185+ c. bench_function ( "nested_jq" , |b| {
186+ b. iter ( || bench_jq ( & data, & filter, & expected) )
187+ } ) ;
96188 }
97189 {
98190 let program = File { code : "\" User: \" + .user.name + \" , Age: \" + (.user.details.age | tostring) + \" , Location: \" + .user.details.location.city + \" , Country: \" + .user.details.location.country" , path : ( ) } ;
99- let loader = Loader :: new ( jaq_std:: defs ( ) ) ;
191+ let defs = jaq_core:: load:: parse ( "def tostring: \" \\ (.)\" ;" , |p| p. defs ( ) ) . unwrap ( ) ;
192+ let loader = Loader :: new ( defs) ;
100193 let arena = Arena :: default ( ) ;
101194 let modules = loader. load ( & arena, program) . unwrap ( ) ;
102195 let filter = jaq_core:: Compiler :: < _ , Native < _ > > :: default ( )
103- . with_funs ( jaq_std:: funs ( ) )
104196 . compile ( modules)
105197 . unwrap ( ) ;
106198
107- c. bench_function ( "nested_jq" , |b| b. iter ( || bench_jq ( & data, & filter, & expected) ) ) ;
199+ c. bench_function ( "nested_jsonlike" , |b| {
200+ b. iter ( || bench_jsonlike ( & data, & filter, & expected) )
201+ } ) ;
108202 }
109203 }
110204}
@@ -123,3 +217,22 @@ fn bench_jq(data: &serde_json::Value, filter: &jaq_core::Filter<Native<Val>>, ex
123217 assert_eq ! ( out. next( ) , Some ( Ok ( Val :: from( expected. to_string( ) ) ) ) ) ;
124218 assert_eq ! ( out. next( ) , None ) ;
125219}
220+
221+ fn bench_jsonlike (
222+ data : & serde_json:: Value ,
223+ filter : & jaq_core:: Filter < Native < JsonLikeHelper < serde_json:: Value > > > ,
224+ expected : & str ,
225+ ) {
226+ let inputs = RcIter :: new ( core:: iter:: empty ( ) ) ;
227+
228+ // iterator over the output values
229+ let mut out = filter. run ( ( Ctx :: new ( [ ] , & inputs) , JsonLikeHelper ( data. clone ( ) ) ) ) ;
230+
231+ assert_eq ! (
232+ out. next( ) ,
233+ Some ( Ok ( JsonLikeHelper ( serde_json:: Value :: String (
234+ expected. to_string( )
235+ ) ) ) )
236+ ) ;
237+ assert_eq ! ( out. next( ) , None ) ;
238+ }
0 commit comments