@@ -81,6 +81,53 @@ def test_static_runner_from_json_not_a_regression():
8181 assert not comparison .regression
8282
8383
84+ def test_static_runner_from_json_multiple_values_not_a_regression ():
85+ # Same as above, but with multiple repetitions
86+ archery_result = {
87+ "suites" : [
88+ {
89+ "name" : "arrow-value-parsing-benchmark" ,
90+ "benchmarks" : [
91+ {
92+ "name" : "FloatParsing<DoubleType>" ,
93+ "unit" : "items_per_second" ,
94+ "less_is_better" : False ,
95+ "values" : [
96+ 93588476.22327498 ,
97+ 94873831.3818328 ,
98+ 95593675.20810866 ,
99+ 95797325.6543961 ,
100+ 96134728.05794072
101+ ],
102+ "time_unit" : "ns" ,
103+ "times" : [
104+ 10537.724568456104 ,
105+ 10575.162068480413 ,
106+ 10599.271208720838 ,
107+ 10679.028059166194 ,
108+ 10827.995119861762
109+ ],
110+ "counters" : {
111+ "family_index" : 0 ,
112+ "per_family_instance_index" : 0 ,
113+ "run_name" : "FloatParsing<DoubleType>" ,
114+ "repetitions" : 5 ,
115+ "repetition_index" : 0 ,
116+ "threads" : 1 ,
117+ "iterations" : 10656
118+ }
119+ }
120+ ]
121+ }
122+ ]
123+ }
124+
125+ contender = StaticBenchmarkRunner .from_json (json .dumps (archery_result ))
126+ baseline = StaticBenchmarkRunner .from_json (json .dumps (archery_result ))
127+ [comparison ] = RunnerComparator (contender , baseline ).comparisons
128+ assert not comparison .regression
129+
130+
84131def test_static_runner_from_json_regression ():
85132 archery_result = {
86133 "suites" : [
@@ -114,6 +161,58 @@ def test_static_runner_from_json_regression():
114161 assert comparison .regression
115162
116163
164+ def test_static_runner_from_json_multiple_values_regression ():
165+ # Same as above, but with multiple repetitions
166+ archery_result = {
167+ "suites" : [
168+ {
169+ "name" : "arrow-value-parsing-benchmark" ,
170+ "benchmarks" : [
171+ {
172+ "name" : "FloatParsing<DoubleType>" ,
173+ "unit" : "items_per_second" ,
174+ "less_is_better" : False ,
175+ "values" : [
176+ 93588476.22327498 ,
177+ 94873831.3818328 ,
178+ 95593675.20810866 ,
179+ 95797325.6543961 ,
180+ 96134728.05794072
181+ ],
182+ "time_unit" : "ns" ,
183+ "times" : [
184+ 10537.724568456104 ,
185+ 10575.162068480413 ,
186+ 10599.271208720838 ,
187+ 10679.028059166194 ,
188+ 10827.995119861762
189+ ],
190+ "counters" : {
191+ "family_index" : 0 ,
192+ "per_family_instance_index" : 0 ,
193+ "run_name" : "FloatParsing<DoubleType>" ,
194+ "repetitions" : 5 ,
195+ "repetition_index" : 0 ,
196+ "threads" : 1 ,
197+ "iterations" : 10656
198+ }
199+ }
200+ ]
201+ }
202+ ]
203+ }
204+
205+ contender = StaticBenchmarkRunner .from_json (json .dumps (archery_result ))
206+
207+ # introduce artificial regression
208+ values = archery_result ['suites' ][0 ]['benchmarks' ][0 ]['values' ]
209+ values [:] = [v * 2 for v in values ]
210+ baseline = StaticBenchmarkRunner .from_json (json .dumps (archery_result ))
211+
212+ [comparison ] = RunnerComparator (contender , baseline ).comparisons
213+ assert comparison .regression
214+
215+
117216def test_benchmark_median ():
118217 assert median ([10 ]) == 10
119218 assert median ([1 , 2 , 3 ]) == 2
@@ -381,3 +480,77 @@ def test_omits_aggregates():
381480 benchmark = GoogleBenchmark (name , [observation1 , observation2 ])
382481 result = json .dumps (benchmark , cls = JsonEncoder )
383482 assert json .loads (result ) == archery_result
483+
484+
485+ def test_multiple_observations ():
486+ name = "FloatParsing<DoubleType>"
487+ google_results = [
488+ {
489+ 'cpu_time' : 10627.38199641615 ,
490+ 'family_index' : 0 ,
491+ 'items_per_second' : 94096551.75067839 ,
492+ 'iterations' : 9487 ,
493+ 'name' : 'FloatParsing<DoubleType>' ,
494+ 'per_family_instance_index' : 0 ,
495+ 'real_time' : 10628.84905663701 ,
496+ 'repetition_index' : 0 ,
497+ 'repetitions' : 3 ,
498+ 'run_name' : 'FloatParsing<DoubleType>' ,
499+ 'run_type' : 'iteration' ,
500+ 'threads' : 1 ,
501+ 'time_unit' : 'ns'
502+ },
503+ {
504+ 'cpu_time' : 10633.318014124594 ,
505+ 'family_index' : 0 ,
506+ 'items_per_second' : 94044022.63448404 ,
507+ 'iterations' : 9487 ,
508+ 'name' : 'FloatParsing<DoubleType>' ,
509+ 'per_family_instance_index' : 0 ,
510+ 'real_time' : 10634.858754122948 ,
511+ 'repetition_index' : 1 ,
512+ 'repetitions' : 3 ,
513+ 'run_name' : 'FloatParsing<DoubleType>' ,
514+ 'run_type' : 'iteration' ,
515+ 'threads' : 1 ,
516+ 'time_unit' : 'ns'
517+ },
518+ {
519+ 'cpu_time' : 10664.315484347 ,
520+ 'family_index' : 0 ,
521+ 'items_per_second' : 93770669.24434038 ,
522+ 'iterations' : 9487 ,
523+ 'name' : 'FloatParsing<DoubleType>' ,
524+ 'per_family_instance_index' : 0 ,
525+ 'real_time' : 10665.584589337563 ,
526+ 'repetition_index' : 2 ,
527+ 'repetitions' : 3 ,
528+ 'run_name' : 'FloatParsing<DoubleType>' ,
529+ 'run_type' : 'iteration' ,
530+ 'threads' : 1 ,
531+ 'time_unit' : 'ns'
532+ }
533+ ]
534+
535+ archery_result = {
536+ 'counters' : {
537+ 'family_index' : 0 ,
538+ 'iterations' : 9487 ,
539+ 'per_family_instance_index' : 0 ,
540+ 'repetition_index' : 2 ,
541+ 'repetitions' : 3 ,
542+ 'run_name' : 'FloatParsing<DoubleType>' ,
543+ 'threads' : 1
544+ },
545+ 'less_is_better' : False ,
546+ 'name' : 'FloatParsing<DoubleType>' ,
547+ 'time_unit' : 'ns' ,
548+ 'times' : [10628.84905663701 , 10634.858754122948 , 10665.584589337563 ],
549+ 'unit' : 'items_per_second' ,
550+ 'values' : [93770669.24434038 , 94044022.63448404 , 94096551.75067839 ]
551+ }
552+
553+ observations = [GoogleBenchmarkObservation (** g ) for g in google_results ]
554+ benchmark = GoogleBenchmark (name , observations )
555+ result = json .dumps (benchmark , cls = JsonEncoder )
556+ assert json .loads (result ) == archery_result
0 commit comments