Skip to content

Commit 33c86b0

Browse files
committed
Implement table printing in Continuous with same code as in Compare
The previous Continuous table printing code had bugs in printing failed results, so better to refactor.
1 parent eb38db3 commit 33c86b0

File tree

4 files changed

+100
-90
lines changed

4 files changed

+100
-90
lines changed

asv/commands/compare.py

Lines changed: 57 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
from __future__ import (absolute_import, division, print_function,
55
unicode_literals)
66

7+
import six
78
import itertools
89

910
from . import Command
@@ -116,24 +117,39 @@ def run(cls, conf, hash_1, hash_2, factor=2, split=False, machine=None):
116117
raise util.UserError(
117118
"Results for machine '{0} not found".format(machine))
118119

120+
cls.print_table(conf, hash_1, hash_2, factor=factor, machine=machine,
121+
split=split)
122+
123+
@classmethod
124+
def print_table(cls, conf, hash_1, hash_2, factor, split,
125+
resultset_1=None, resultset_2=None, machine=None,
126+
sort_by_ratio=False, only_changed=False):
119127
results_1 = {}
120128
results_2 = {}
121129

122-
for result in iter_results_for_machine_and_hash(
123-
conf.results_dir, machine, hash_1):
124-
for key in result.results:
125-
for name, value in unroll_result(key, result.results[key]):
126-
if name not in results_1:
127-
results_1[name] = []
128-
results_1[name].append(value)
129-
130-
for result in iter_results_for_machine_and_hash(
131-
conf.results_dir, machine, hash_2):
132-
for key in result.results:
133-
for name, value in unroll_result(key, result.results[key]):
134-
if name not in results_2:
135-
results_2[name] = []
136-
results_2[name].append(value)
130+
def results_default_iter(commit_hash):
131+
for result in iter_results_for_machine_and_hash(
132+
conf.results_dir, machine, commit_hash):
133+
for key, value in six.iteritems(result.results):
134+
yield key, value
135+
136+
if resultset_1 is None:
137+
resultset_1 = results_default_iter(hash_1)
138+
139+
if resultset_2 is None:
140+
resultset_2 = results_default_iter(hash_2)
141+
142+
for key, result in resultset_1:
143+
for name, value in unroll_result(key, result):
144+
if name not in results_1:
145+
results_1[name] = []
146+
results_1[name].append(value)
147+
148+
for key, result in resultset_2:
149+
for name, value in unroll_result(key, result):
150+
if name not in results_2:
151+
results_2[name] = []
152+
results_2[name].append(value)
137153

138154
if len(results_1) == 0:
139155
raise util.UserError(
@@ -157,6 +173,9 @@ def run(cls, conf, hash_1, hash_2, factor=2, split=False, machine=None):
157173
else:
158174
bench['all'] = []
159175

176+
worsened = False
177+
improved = False
178+
160179
for benchmark in joint_benchmarks:
161180
if benchmark in results_1:
162181
time_1 = mean(results_1[benchmark])
@@ -170,20 +189,25 @@ def run(cls, conf, hash_1, hash_2, factor=2, split=False, machine=None):
170189

171190
if _isna(time_1) or _isna(time_2):
172191
ratio = 'n/a'
192+
ratio_num = 1e9
173193
else:
174194
try:
175-
ratio = "{0:6.2f}".format(time_2 / time_1)
195+
ratio_num = time_2 / time_1
196+
ratio = "{0:6.2f}".format(ratio_num)
176197
except ZeroDivisionError:
198+
ratio_num = 1e9
177199
ratio = "n/a"
178200

179201
if time_1 is not None and time_2 is None:
180202
# introduced a failure
181203
color = 'red'
182204
mark = '!'
205+
worsened = True
183206
elif time_1 is None and time_2 is not None:
184207
# fixed a failure
185208
color = 'green'
186209
mark = ' '
210+
improved = True
187211
elif time_1 is None and time_2 is None:
188212
# both failed
189213
color = 'red'
@@ -195,23 +219,28 @@ def run(cls, conf, hash_1, hash_2, factor=2, split=False, machine=None):
195219
elif time_2 < time_1 / factor:
196220
color = 'green'
197221
mark = '-'
222+
improved = True
198223
elif time_2 > time_1 * factor:
199224
color = 'red'
200225
mark = '+'
226+
worsened = True
201227
else:
202228
color = 'default'
203229
mark = ' '
204230

231+
if only_changed and mark == ' ':
232+
continue
233+
205234
details = "{0:1s} {1:>9s} {2:>9s} {3:>9s} ".format(
206235
mark,
207236
human_value(time_1, "seconds"),
208237
human_value(time_2, "seconds"),
209238
ratio)
210239

211240
if split:
212-
bench[color].append((color, details, benchmark))
241+
bench[color].append((color, details, benchmark, ratio_num))
213242
else:
214-
bench['all'].append((color, details, benchmark))
243+
bench['all'].append((color, details, benchmark, ratio_num))
215244

216245
if split:
217246
keys = ['green', 'default', 'red']
@@ -229,12 +258,18 @@ def run(cls, conf, hash_1, hash_2, factor=2, split=False, machine=None):
229258
if len(bench[key]) == 0:
230259
continue
231260

232-
print("")
233-
print(titles[key])
234-
print("")
261+
if not only_changed:
262+
print("")
263+
print(titles[key])
264+
print("")
235265
print(" before after ratio")
236266
print(" [{0:8s}] [{1:8s}]".format(hash_1[:8], hash_2[:8]))
237267

238-
for color, details, benchmark in bench[key]:
268+
if sort_by_ratio:
269+
bench[key].sort(key=lambda v: v[3], reverse=True)
270+
271+
for color, details, benchmark, ratio in bench[key]:
239272
color_print(details, color, end='')
240273
print(benchmark)
274+
275+
return worsened, improved

asv/commands/continuous.py

Lines changed: 19 additions & 67 deletions
Original file line numberDiff line numberDiff line change
@@ -5,17 +5,15 @@
55
unicode_literals)
66

77
import os
8-
98
import six
109

1110
from . import Command
1211
from .run import Run
13-
from .compare import unroll_result
12+
from .compare import Compare
1413

15-
from ..console import truncate_left, color_print
1614
from ..repo import get_repo
15+
from ..console import color_print
1716
from .. import results
18-
from .. import util
1917

2018
from . import common_args
2119

@@ -75,73 +73,27 @@ def run(cls, conf, branch=None, base=None, factor=2.0, show_stderr=False, bench=
7573
if result:
7674
return result
7775

78-
tabulated = []
79-
all_benchmarks = {}
80-
for commit_hash in commit_hashes:
81-
subtab = {}
82-
totals = {}
83-
76+
def results_iter(commit_hash):
8477
for env in run_objs['environments']:
8578
filename = results.get_filename(
8679
run_objs['machine_params']['machine'], commit_hash, env.name)
8780
filename = os.path.join(conf.results_dir, filename)
8881
result = results.Results.load(filename)
89-
90-
for benchmark_name, benchmark in six.iteritems(run_objs['benchmarks']):
91-
for name, value in unroll_result(benchmark_name,
92-
result.results.get(benchmark_name, None)):
93-
if value is not None:
94-
all_benchmarks[name] = benchmark
95-
subtab.setdefault(name, 0.0)
96-
totals.setdefault(name, 0)
97-
subtab[name] += value
98-
totals[name] += 1
99-
100-
for name in totals.keys():
101-
subtab[name] /= totals[name]
102-
103-
tabulated.append(subtab)
104-
105-
after, before = tabulated
106-
107-
table = []
108-
slowed_down = False
109-
for name, benchmark in six.iteritems(all_benchmarks):
110-
if before[name] == 0:
111-
if after[name] == 0:
112-
change = 1.0
113-
else:
114-
change = float('inf')
115-
else:
116-
change = after[name] / before[name]
117-
118-
if change > factor or change < 1.0 / factor:
119-
table.append(
120-
(change, before[name], after[name], name, benchmark))
121-
if change > factor:
122-
slowed_down = True
123-
124-
print("")
125-
126-
if not len(table):
82+
for name, benchmark in six.iteritems(run_objs['benchmarks']):
83+
yield name, result.results.get(name, float("nan"))
84+
85+
status = Compare.print_table(conf, parent, head,
86+
resultset_1=results_iter(parent),
87+
resultset_2=results_iter(head),
88+
factor=factor, split=False, only_changed=True,
89+
sort_by_ratio=True)
90+
worsened, improved = status
91+
92+
if worsened:
93+
color_print("SOME BENCHMARKS HAVE CHANGED SIGNIFICANTLY.\n", 'red')
94+
elif improved:
95+
color_print("SOME BENCHMARKS HAVE CHANGED SIGNIFICANTLY.\n", 'green')
96+
else:
12797
color_print("BENCHMARKS NOT SIGNIFICANTLY CHANGED.\n", 'green')
128-
return 0
129-
130-
table.sort(reverse=True)
131-
132-
color_print(
133-
"{0:40s} {1:>8} {2:>8} {3:>8}\n".format("BENCHMARK", "BEFORE", "AFTER", "FACTOR"),
134-
'blue')
135-
for change, before, after, name, benchmark in table:
136-
before_display = util.human_value(before, benchmark['unit'])
137-
after_display = util.human_value(after, benchmark['unit'])
138-
139-
print("{0:40s} {1:>8} {2:>8} {3:.8f}x".format(
140-
truncate_left(name, 40),
141-
before_display, after_display, change))
142-
143-
print("")
144-
color_print(
145-
"SOME BENCHMARKS HAVE CHANGED SIGNIFICANTLY.\n", 'red')
14698

147-
return slowed_down
99+
return worsened

test/test_compare.py

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,20 @@
4545
11.87μs 13.10μs 1.10 time_units.time_very_simple_unit_parse
4646
"""
4747

48+
REFERENCE_ONLY_CHANGED = """
49+
before after ratio
50+
[22b920c6] [fcf8c079]
51+
! n/a failed n/a params_examples.ParamSuite.track_value
52+
! 454.03μs failed n/a time_coordinates.time_latitude
53+
! 3.00s failed n/a time_other.time_parameterized(3)
54+
+ 933.71μs 108.22ms 115.90 time_quantity.time_quantity_init_array
55+
+ 1.75ms 152.84ms 87.28 time_quantity.time_quantity_array_conversion
56+
+ 372.11μs 11.47ms 30.81 time_units.time_unit_parse
57+
+ 125.11μs 3.81ms 30.42 time_units.time_simple_unit_parse
58+
+ 1.31ms 7.75ms 5.91 time_quantity.time_quantity_ufunc_sin
59+
- 69.09μs 18.32μs 0.27 time_units.time_unit_to
60+
"""
61+
4862
def test_compare(capsys, tmpdir):
4963
tmpdir = six.text_type(tmpdir)
5064
os.chdir(tmpdir)
@@ -60,3 +74,12 @@ def test_compare(capsys, tmpdir):
6074

6175
text, err = capsys.readouterr()
6276
assert text.strip() == REFERENCE.strip()
77+
78+
# Check print_table output as called from Continuous
79+
status = Compare.print_table(conf, '22b920c6', 'fcf8c079', factor=2, machine='cheetah',
80+
split=False, only_changed=True, sort_by_ratio=True)
81+
worsened, improved = status
82+
assert worsened
83+
assert improved
84+
text, err = capsys.readouterr()
85+
assert text.strip() == REFERENCE_ONLY_CHANGED.strip()

test/test_workflow.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -141,7 +141,7 @@ def test_continuous(capfd, basic_conf):
141141

142142
text, err = capfd.readouterr()
143143
assert "SOME BENCHMARKS HAVE CHANGED SIGNIFICANTLY" in text
144-
assert "params_examples.track_find_test(2) 1.0 6.0 6.00000000x" in text
144+
assert "+ 1.00s 6.00s 6.00 params_examples.track_find_test(2)" in text
145145
assert "params_examples.ClassOne" in text
146146

147147

0 commit comments

Comments
 (0)