1
1
#!/usr/bin/env python3
2
2
3
3
"""
4
- Measure or compare sizes of a list of files.
4
+ Compare sizes of a list of files.
5
5
6
6
This produces the format for use in https://github.com/benchmark-action/github-action-benchmark.
7
7
8
8
Use the script:
9
- python3 scripts/ci/sizes .py --help
9
+ python3 scripts/ci/compare .py --help
10
10
11
- python3 scripts/ci/sizes.py measure \
12
- "Wasm":web_viewer/re_viewer_bg.wasm
13
-
14
- python3 scripts/ci/sizes.py measure --format=github \
15
- "Wasm":web_viewer/re_viewer_bg.wasm
16
-
17
- python3 scripts/ci/sizes.py compare --threshold=20 previous.json current.json
11
+ python3 scripts/ci/compare.py --threshold=20 previous.json current.json
18
12
"""
19
13
from __future__ import annotations
20
14
21
15
import argparse
22
16
import json
23
- import os .path
24
17
import sys
25
- from enum import Enum
26
18
from pathlib import Path
27
19
from typing import Any
28
20
@@ -78,17 +70,6 @@ def render_table_rows(rows: list[Any], headers: list[str]) -> str:
78
70
return table
79
71
80
72
81
- class Format (Enum ):
82
- JSON = "json"
83
- GITHUB = "github"
84
-
85
- def render (self , data : list [dict [str , str ]]) -> str :
86
- if self is Format .JSON :
87
- return json .dumps (data )
88
- if self is Format .GITHUB :
89
- return render_table_dict (data )
90
-
91
-
92
73
def compare (
93
74
previous_path : str ,
94
75
current_path : str ,
@@ -113,23 +94,40 @@ def compare(
113
94
rows : list [tuple [str , str , str , str ]] = []
114
95
for name , entry in entries .items ():
115
96
if "previous" in entry and "current" in entry :
116
- previous_bytes = float (entry ["previous" ]["value" ]) * DIVISORS [entry ["previous" ]["unit" ]]
117
- current_bytes = float (entry ["current" ]["value" ]) * DIVISORS [entry ["current" ]["unit" ]]
118
- unit = get_unit (min (previous_bytes , current_bytes ))
119
- div = get_divisor (unit )
120
-
121
- abs_diff_bytes = abs (current_bytes - previous_bytes )
122
- min_diff_bytes = previous_bytes * (threshold_pct / 100 )
123
- if abs_diff_bytes >= min_diff_bytes :
97
+ previous_unit = entry ["previous" ]["unit" ]
98
+ current_unit = entry ["current" ]["unit" ]
99
+
100
+ previous = float (entry ["previous" ]["value" ])
101
+ current = float (entry ["current" ]["value" ])
102
+
103
+ if previous_unit == current_unit :
104
+ div = 1
105
+ unit = previous_unit
106
+ else :
107
+ previous_divisor = DIVISORS .get (previous_unit , 1 )
108
+ current_divisor = DIVISORS .get (current_unit , 1 )
109
+
110
+ previous_bytes = previous * previous_divisor
111
+ current_bytes = current * current_divisor
112
+
124
113
previous = previous_bytes / div
125
114
current = current_bytes / div
126
- change_pct = ((current_bytes - previous_bytes ) / previous_bytes ) * 100
115
+
116
+ unit = get_unit (min (previous_bytes , current_bytes ))
117
+ div = get_divisor (unit )
118
+
119
+ change_pct = ((current - previous ) / previous ) * 100
120
+ if abs (change_pct ) >= threshold_pct :
121
+ if unit in DIVISORS :
122
+ change = f"{ change_pct :+.2f} %"
123
+ else :
124
+ change = f"{ format_num (current - previous )} { unit } "
127
125
rows .append (
128
126
(
129
127
name ,
130
- f"{ previous :.2f } { unit } " ,
131
- f"{ current :.2f } { unit } " ,
132
- f" { change_pct :+.2f } %" ,
128
+ f"{ format_num ( previous ) } { unit } " ,
129
+ f"{ format_num ( current ) } { unit } " ,
130
+ change ,
133
131
)
134
132
)
135
133
elif "current" in entry :
@@ -148,85 +146,52 @@ def compare(
148
146
sys .stdout .flush ()
149
147
150
148
151
- def measure (files : list [str ], format : Format ) -> None :
152
- output : list [dict [str , str ]] = []
153
- for arg in files :
154
- parts = arg .split (":" )
155
- name = parts [0 ]
156
- file = parts [1 ]
157
- size = os .path .getsize (file )
158
- unit = parts [2 ] if len (parts ) > 2 else get_unit (size )
159
- div = get_divisor (unit )
160
-
161
- output .append (
162
- {
163
- "name" : name ,
164
- "value" : str (round (size / div , 2 )),
165
- "unit" : unit ,
166
- }
167
- )
149
+ def format_num (num : float ) -> str :
150
+ if num .is_integer ():
151
+ return str (int (num ))
152
+ return f"{ num :.2f} "
168
153
169
- sys .stdout .write (format .render (output ))
170
- sys .stdout .flush ()
171
154
172
-
173
- def percentage (value : str ) -> int :
155
+ def percentage (value : str ) -> float :
174
156
value = value .replace ("%" , "" )
175
- return int (value )
157
+ return float (value )
176
158
177
159
178
160
def main () -> None :
179
161
parser = argparse .ArgumentParser (description = "Generate a PR summary page" )
180
-
181
- cmds_parser = parser .add_subparsers (title = "cmds" , dest = "cmd" , help = "Command" )
182
-
183
- compare_parser = cmds_parser .add_parser ("compare" , help = "Compare results" )
184
- compare_parser .add_argument ("before" , type = str , help = "Previous result .json file" )
185
- compare_parser .add_argument ("after" , type = str , help = "Current result .json file" )
186
- compare_parser .add_argument (
162
+ parser .add_argument ("before" , type = str , help = "Previous result .json file" )
163
+ parser .add_argument ("after" , type = str , help = "Current result .json file" )
164
+ parser .add_argument (
187
165
"--threshold" ,
188
166
type = percentage ,
189
167
required = False ,
190
168
default = 20 ,
191
169
help = "Only print row if value is N%% larger or smaller" ,
192
170
)
193
- compare_parser .add_argument (
171
+ parser .add_argument (
194
172
"--before-header" ,
195
173
type = str ,
196
174
required = False ,
197
175
default = "Before" ,
198
176
help = "Header for before column" ,
199
177
)
200
- compare_parser .add_argument (
178
+ parser .add_argument (
201
179
"--after-header" ,
202
180
type = str ,
203
181
required = False ,
204
182
default = "After" ,
205
183
help = "Header for after column" ,
206
184
)
207
185
208
- measure_parser = cmds_parser .add_parser ("measure" , help = "Measure sizes" )
209
- measure_parser .add_argument (
210
- "--format" ,
211
- type = Format ,
212
- choices = list (Format ),
213
- default = Format .JSON ,
214
- help = "Format to render" ,
215
- )
216
- measure_parser .add_argument ("files" , nargs = "*" , help = "Entries to measure. Format: name:path[:unit]" )
217
-
218
186
args = parser .parse_args ()
219
187
220
- if args .cmd == "compare" :
221
- compare (
222
- args .before ,
223
- args .after ,
224
- args .threshold ,
225
- args .before_header ,
226
- args .after_header ,
227
- )
228
- elif args .cmd == "measure" :
229
- measure (args .files , args .format )
188
+ compare (
189
+ args .before ,
190
+ args .after ,
191
+ args .threshold ,
192
+ args .before_header ,
193
+ args .after_header ,
194
+ )
230
195
231
196
232
197
if __name__ == "__main__" :
0 commit comments