A couple of script changes after CI integration

- Renamed struct_.py -> structs.py again.

- Removed lfs.csv, instead prefering script specific csv files.

- Added *-diff make rules for quick comparison against a previous
  result, results are now implicitly written on each run.

  For example, `make code` creates lfs.code.csv and prints the summary, which
  can be followed by `make code-diff` to compare changes against the saved
  lfs.code.csv without overwriting.

- Added nargs=? support for -s and -S, now uses a per-result _sort
  attribute to decide sort if fields are unspecified.
This commit is contained in:
Christopher Haster
2022-11-29 14:10:50 -06:00
parent 9990342440
commit c4b3e9d826
10 changed files with 380 additions and 208 deletions
+21 -11
View File
@@ -112,6 +112,7 @@ class CodeResult(co.namedtuple('CodeResult', [
'size'])):
_by = ['file', 'function']
_fields = ['size']
_sort = ['size']
_types = {'size': Int}
__slots__ = ()
@@ -385,8 +386,12 @@ def table(Result, results, diff_results=None, *,
reverse=True)
if sort:
for k, reverse in reversed(sort):
names.sort(key=lambda n: (getattr(table[n], k),)
if getattr(table.get(n), k, None) is not None else (),
names.sort(
key=lambda n: tuple(
(getattr(table[n], k),)
if getattr(table.get(n), k, None) is not None else ()
for k in ([k] if k else [
k for k in Result._sort if k in fields])),
reverse=reverse ^ (not k or k in Result._fields))
@@ -544,8 +549,10 @@ def main(obj_paths, *,
results.sort()
if sort:
for k, reverse in reversed(sort):
results.sort(key=lambda r: (getattr(r, k),)
if getattr(r, k) is not None else (),
results.sort(
key=lambda r: tuple(
(getattr(r, k),) if getattr(r, k) is not None else ()
for k in ([k] if k else CodeResult._sort)),
reverse=reverse ^ (not k or k in CodeResult._fields))
# write results to CSV
@@ -553,14 +560,15 @@ def main(obj_paths, *,
with openio(args['output'], 'w') as f:
writer = csv.DictWriter(f,
(by if by is not None else CodeResult._by)
+ ['code_'+k for k in CodeResult._fields])
+ ['code_'+k for k in (
fields if fields is not None else CodeResult._fields)])
writer.writeheader()
for r in results:
writer.writerow(
{k: getattr(r, k)
for k in (by if by is not None else CodeResult._by)}
| {'code_'+k: getattr(r, k)
for k in CodeResult._fields})
{k: getattr(r, k) for k in (
by if by is not None else CodeResult._by)}
| {'code_'+k: getattr(r, k) for k in (
fields if fields is not None else CodeResult._fields)})
# find previous results?
if args.get('diff'):
@@ -655,12 +663,14 @@ if __name__ == "__main__":
namespace.sort.append((value, True if option == '-S' else False))
parser.add_argument(
'-s', '--sort',
nargs='?',
action=AppendSort,
help="Sort by this fields.")
help="Sort by this field.")
parser.add_argument(
'-S', '--reverse-sort',
nargs='?',
action=AppendSort,
help="Sort by this fields, but backwards.")
help="Sort by this field, but backwards.")
parser.add_argument(
'-Y', '--summary',
action='store_true',
+19 -9
View File
@@ -180,6 +180,7 @@ class CovResult(co.namedtuple('CovResult', [
'calls', 'hits', 'funcs', 'lines', 'branches'])):
_by = ['file', 'function', 'line']
_fields = ['calls', 'hits', 'funcs', 'lines', 'branches']
_sort = ['funcs', 'lines', 'branches', 'hits', 'calls']
_types = {
'calls': Int, 'hits': Int,
'funcs': Frac, 'lines': Frac, 'branches': Frac}
@@ -372,8 +373,12 @@ def table(Result, results, diff_results=None, *,
reverse=True)
if sort:
for k, reverse in reversed(sort):
names.sort(key=lambda n: (getattr(table[n], k),)
if getattr(table.get(n), k, None) is not None else (),
names.sort(
key=lambda n: tuple(
(getattr(table[n], k),)
if getattr(table.get(n), k, None) is not None else ()
for k in ([k] if k else [
k for k in Result._sort if k in fields])),
reverse=reverse ^ (not k or k in Result._fields))
@@ -617,8 +622,10 @@ def main(gcda_paths, *,
results.sort()
if sort:
for k, reverse in reversed(sort):
results.sort(key=lambda r: (getattr(r, k),)
if getattr(r, k) is not None else (),
results.sort(
key=lambda r: tuple(
(getattr(r, k),) if getattr(r, k) is not None else ()
for k in ([k] if k else CovResult._sort)),
reverse=reverse ^ (not k or k in CovResult._fields))
# write results to CSV
@@ -626,14 +633,15 @@ def main(gcda_paths, *,
with openio(args['output'], 'w') as f:
writer = csv.DictWriter(f,
(by if by is not None else CovResult._by)
+ ['cov_'+k for k in CovResult._fields])
+ ['cov_'+k for k in (
fields if fields is not None else CovResult._fields)])
writer.writeheader()
for r in results:
writer.writerow(
{k: getattr(r, k)
for k in (by if by is not None else CovResult._by)}
| {'cov_'+k: getattr(r, k)
for k in CovResult._fields})
{k: getattr(r, k) for k in (
by if by is not None else CovResult._by)}
| {'cov_'+k: getattr(r, k) for k in (
fields if fields is not None else CovResult._fields)})
# find previous results?
if args.get('diff'):
@@ -748,10 +756,12 @@ if __name__ == "__main__":
namespace.sort.append((value, True if option == '-S' else False))
parser.add_argument(
'-s', '--sort',
nargs='?',
action=AppendSort,
help="Sort by this field.")
parser.add_argument(
'-S', '--reverse-sort',
nargs='?',
action=AppendSort,
help="Sort by this field, but backwards.")
parser.add_argument(
+21 -11
View File
@@ -112,6 +112,7 @@ class DataResult(co.namedtuple('DataResult', [
'size'])):
_by = ['file', 'function']
_fields = ['size']
_sort = ['size']
_types = {'size': Int}
__slots__ = ()
@@ -385,8 +386,12 @@ def table(Result, results, diff_results=None, *,
reverse=True)
if sort:
for k, reverse in reversed(sort):
names.sort(key=lambda n: (getattr(table[n], k),)
if getattr(table.get(n), k, None) is not None else (),
names.sort(
key=lambda n: tuple(
(getattr(table[n], k),)
if getattr(table.get(n), k, None) is not None else ()
for k in ([k] if k else [
k for k in Result._sort if k in fields])),
reverse=reverse ^ (not k or k in Result._fields))
@@ -541,8 +546,10 @@ def main(obj_paths, *,
results.sort()
if sort:
for k, reverse in reversed(sort):
results.sort(key=lambda r: (getattr(r, k),)
if getattr(r, k) is not None else (),
results.sort(
key=lambda r: tuple(
(getattr(r, k),) if getattr(r, k) is not None else ()
for k in ([k] if k else DataResult._sort)),
reverse=reverse ^ (not k or k in DataResult._fields))
# write results to CSV
@@ -550,14 +557,15 @@ def main(obj_paths, *,
with openio(args['output'], 'w') as f:
writer = csv.DictWriter(f,
(by if by is not None else DataResult._by)
+ ['data_'+k for k in DataResult._fields])
+ ['data_'+k for k in (
fields if fields is not None else DataResult._fields)])
writer.writeheader()
for r in results:
writer.writerow(
{k: getattr(r, k)
for k in (by if by is not None else DataResult._by)}
| {'data_'+k: getattr(r, k)
for k in DataResult._fields})
{k: getattr(r, k) for k in (
by if by is not None else DataResult._by)}
| {'data_'+k: getattr(r, k) for k in (
fields if fields is not None else DataResult._fields)})
# find previous results?
if args.get('diff'):
@@ -652,12 +660,14 @@ if __name__ == "__main__":
namespace.sort.append((value, True if option == '-S' else False))
parser.add_argument(
'-s', '--sort',
nargs='?',
action=AppendSort,
help="Sort by this fields.")
help="Sort by this field.")
parser.add_argument(
'-S', '--reverse-sort',
nargs='?',
action=AppendSort,
help="Sort by this fields, but backwards.")
help="Sort by this field, but backwards.")
parser.add_argument(
'-Y', '--summary',
action='store_true',
+29 -13
View File
@@ -122,6 +122,7 @@ class PerfResult(co.namedtuple('PerfResult', [
'children'])):
_by = ['file', 'function', 'line']
_fields = ['cycles', 'bmisses', 'branches', 'cmisses', 'caches']
_sort = ['cycles', 'bmisses', 'cmisses', 'branches', 'caches']
_types = {
'cycles': Int,
'bmisses': Int, 'branches': Int,
@@ -712,10 +713,15 @@ def table(Result, results, diff_results=None, *,
reverse=True)
if sort:
for k, reverse in reversed(sort):
names.sort(key=lambda n: (getattr(table[n], k),)
if getattr(table.get(n), k, None) is not None else (),
names.sort(
key=lambda n: tuple(
(getattr(table[n], k),)
if getattr(table.get(n), k, None) is not None else ()
for k in ([k] if k else [
k for k in Result._sort if k in fields])),
reverse=reverse ^ (not k or k in Result._fields))
# build up our lines
lines = []
@@ -853,8 +859,13 @@ def table(Result, results, diff_results=None, *,
names_.sort()
if sort:
for k, reverse in reversed(sort):
names_.sort(key=lambda n: (getattr(table_[n], k),)
if getattr(table_.get(n), k, None) is not None else (),
names_.sort(
key=lambda n: tuple(
(getattr(table_[n], k),)
if getattr(table_.get(n), k, None) is not None
else ()
for k in ([k] if k else [
k for k in Result._sort if k in fields])),
reverse=reverse ^ (not k or k in Result._fields))
for i, name in enumerate(names_):
@@ -1051,8 +1062,10 @@ def report(perf_paths, *,
results.sort()
if sort:
for k, reverse in reversed(sort):
results.sort(key=lambda r: (getattr(r, k),)
if getattr(r, k) is not None else (),
results.sort(
key=lambda r: tuple(
(getattr(r, k),) if getattr(r, k) is not None else ()
for k in ([k] if k else PerfResult._sort)),
reverse=reverse ^ (not k or k in PerfResult._fields))
# write results to CSV
@@ -1060,14 +1073,15 @@ def report(perf_paths, *,
with openio(args['output'], 'w') as f:
writer = csv.DictWriter(f,
(by if by is not None else PerfResult._by)
+ ['perf_'+k for k in PerfResult._fields])
+ ['perf_'+k for k in (
fields if fields is not None else PerfResult._fields)])
writer.writeheader()
for r in results:
writer.writerow(
{k: getattr(r, k)
for k in (by if by is not None else PerfResult._by)}
| {'perf_'+k: getattr(r, k)
for k in PerfResult._fields})
{k: getattr(r, k) for k in (
by if by is not None else PerfResult._by)}
| {'perf_'+k: getattr(r, k) for k in (
fields if fields is not None else PerfResult._fields)})
# find previous results?
if args.get('diff'):
@@ -1192,12 +1206,14 @@ if __name__ == "__main__":
namespace.sort.append((value, True if option == '-S' else False))
parser.add_argument(
'-s', '--sort',
nargs='?',
action=AppendSort,
help="Sort by this fields.")
help="Sort by this field.")
parser.add_argument(
'-S', '--reverse-sort',
nargs='?',
action=AppendSort,
help="Sort by this fields, but backwards.")
help="Sort by this field, but backwards.")
parser.add_argument(
'-Y', '--summary',
action='store_true',
+29 -13
View File
@@ -113,6 +113,7 @@ class PerfBdResult(co.namedtuple('PerfBdResult', [
'children'])):
_by = ['file', 'function', 'line']
_fields = ['readed', 'proged', 'erased']
_sort = ['erased', 'proged', 'readed']
_types = {'readed': Int, 'proged': Int, 'erased': Int}
__slots__ = ()
@@ -678,10 +679,15 @@ def table(Result, results, diff_results=None, *,
reverse=True)
if sort:
for k, reverse in reversed(sort):
names.sort(key=lambda n: (getattr(table[n], k),)
if getattr(table.get(n), k, None) is not None else (),
names.sort(
key=lambda n: tuple(
(getattr(table[n], k),)
if getattr(table.get(n), k, None) is not None else ()
for k in ([k] if k else [
k for k in Result._sort if k in fields])),
reverse=reverse ^ (not k or k in Result._fields))
# build up our lines
lines = []
@@ -819,8 +825,13 @@ def table(Result, results, diff_results=None, *,
names_.sort()
if sort:
for k, reverse in reversed(sort):
names_.sort(key=lambda n: (getattr(table_[n], k),)
if getattr(table_.get(n), k, None) is not None else (),
names_.sort(
key=lambda n: tuple(
(getattr(table_[n], k),)
if getattr(table_.get(n), k, None) is not None
else ()
for k in ([k] if k else [
k for k in Result._sort if k in fields])),
reverse=reverse ^ (not k or k in Result._fields))
for i, name in enumerate(names_):
@@ -1031,8 +1042,10 @@ def report(obj_path='', trace_paths=[], *,
results.sort()
if sort:
for k, reverse in reversed(sort):
results.sort(key=lambda r: (getattr(r, k),)
if getattr(r, k) is not None else (),
results.sort(
key=lambda r: tuple(
(getattr(r, k),) if getattr(r, k) is not None else ()
for k in ([k] if k else PerfBdResult._sort)),
reverse=reverse ^ (not k or k in PerfBdResult._fields))
# write results to CSV
@@ -1040,14 +1053,15 @@ def report(obj_path='', trace_paths=[], *,
with openio(args['output'], 'w') as f:
writer = csv.DictWriter(f,
(by if by is not None else PerfBdResult._by)
+ ['perfbd_'+k for k in PerfBdResult._fields])
+ ['perfbd_'+k for k in (
fields if fields is not None else PerfBdResult._fields)])
writer.writeheader()
for r in results:
writer.writerow(
{k: getattr(r, k)
for k in (by if by is not None else PerfBdResult._by)}
| {'perfbd_'+k: getattr(r, k)
for k in PerfBdResult._fields})
{k: getattr(r, k) for k in (
by if by is not None else PerfBdResult._by)}
| {'perfbd_'+k: getattr(r, k) for k in (
fields if fields is not None else PerfBdResult._fields)})
# find previous results?
if args.get('diff'):
@@ -1164,12 +1178,14 @@ if __name__ == "__main__":
namespace.sort.append((value, True if option == '-S' else False))
parser.add_argument(
'-s', '--sort',
nargs='?',
action=AppendSort,
help="Sort by this fields.")
help="Sort by this field.")
parser.add_argument(
'-S', '--reverse-sort',
nargs='?',
action=AppendSort,
help="Sort by this fields, but backwards.")
help="Sort by this field, but backwards.")
parser.add_argument(
'-Y', '--summary',
action='store_true',
+21 -11
View File
@@ -102,6 +102,7 @@ class StackResult(co.namedtuple('StackResult', [
'file', 'function', 'frame', 'limit', 'children'])):
_by = ['file', 'function']
_fields = ['frame', 'limit']
_sort = ['limit', 'frame']
_types = {'frame': Int, 'limit': Int}
__slots__ = ()
@@ -350,8 +351,12 @@ def table(Result, results, diff_results=None, *,
reverse=True)
if sort:
for k, reverse in reversed(sort):
names.sort(key=lambda n: (getattr(table[n], k),)
if getattr(table.get(n), k, None) is not None else (),
names.sort(
key=lambda n: tuple(
(getattr(table[n], k),)
if getattr(table.get(n), k, None) is not None else ()
for k in ([k] if k else [
k for k in Result._sort if k in fields])),
reverse=reverse ^ (not k or k in Result._fields))
@@ -569,8 +574,10 @@ def main(ci_paths,
results.sort()
if sort:
for k, reverse in reversed(sort):
results.sort(key=lambda r: (getattr(r, k),)
if getattr(r, k) is not None else (),
results.sort(
key=lambda r: tuple(
(getattr(r, k),) if getattr(r, k) is not None else ()
for k in ([k] if k else StackResult._sort)),
reverse=reverse ^ (not k or k in StackResult._fields))
# write results to CSV
@@ -578,14 +585,15 @@ def main(ci_paths,
with openio(args['output'], 'w') as f:
writer = csv.DictWriter(f,
(by if by is not None else StackResult._by)
+ ['stack_'+k for k in StackResult._fields])
+ ['stack_'+k for k in (
fields if fields is not None else StackResult._fields)])
writer.writeheader()
for r in results:
writer.writerow(
{k: getattr(r, k)
for k in (by if by is not None else StackResult._by)}
| {'stack_'+k: getattr(r, k)
for k in StackResult._fields})
{k: getattr(r, k) for k in (
by if by is not None else StackResult._by)}
| {'stack_'+k: getattr(r, k) for k in (
fields if fields is not None else StackResult._fields)})
# find previous results?
if args.get('diff'):
@@ -685,12 +693,14 @@ if __name__ == "__main__":
namespace.sort.append((value, True if option == '-S' else False))
parser.add_argument(
'-s', '--sort',
nargs='?',
action=AppendSort,
help="Sort by this fields.")
help="Sort by this field.")
parser.add_argument(
'-S', '--reverse-sort',
nargs='?',
action=AppendSort,
help="Sort by this fields, but backwards.")
help="Sort by this field, but backwards.")
parser.add_argument(
'-Y', '--summary',
action='store_true',
+20 -10
View File
@@ -3,7 +3,7 @@
# Script to find struct sizes.
#
# Example:
# ./scripts/struct_.py lfs.o lfs_util.o -Ssize
# ./scripts/structs.py lfs.o lfs_util.o -Ssize
#
# Copyright (c) 2022, The littlefs authors.
# SPDX-License-Identifier: BSD-3-Clause
@@ -106,6 +106,7 @@ class Int(co.namedtuple('Int', 'x')):
class StructResult(co.namedtuple('StructResult', ['file', 'struct', 'size'])):
_by = ['file', 'struct']
_fields = ['size']
_sort = ['size']
_types = {'size': Int}
__slots__ = ()
@@ -333,8 +334,12 @@ def table(Result, results, diff_results=None, *,
reverse=True)
if sort:
for k, reverse in reversed(sort):
names.sort(key=lambda n: (getattr(table[n], k),)
if getattr(table.get(n), k, None) is not None else (),
names.sort(
key=lambda n: tuple(
(getattr(table[n], k),)
if getattr(table.get(n), k, None) is not None else ()
for k in ([k] if k else [
k for k in Result._sort if k in fields])),
reverse=reverse ^ (not k or k in Result._fields))
@@ -494,8 +499,10 @@ def main(obj_paths, *,
results.sort()
if sort:
for k, reverse in reversed(sort):
results.sort(key=lambda r: (getattr(r, k),)
if getattr(r, k) is not None else (),
results.sort(
key=lambda r: tuple(
(getattr(r, k),) if getattr(r, k) is not None else ()
for k in ([k] if k else StructResult._sort)),
reverse=reverse ^ (not k or k in StructResult._fields))
# write results to CSV
@@ -503,14 +510,15 @@ def main(obj_paths, *,
with openio(args['output'], 'w') as f:
writer = csv.DictWriter(f,
(by if by is not None else StructResult._by)
+ ['struct_'+k for k in StructResult._fields])
+ ['struct_'+k for k in (
fields if fields is not None else StructResult._fields)])
writer.writeheader()
for r in results:
writer.writerow(
{k: getattr(r, k)
for k in (by if by is not None else StructResult._by)}
| {'struct_'+k: getattr(r, k)
for k in StructResult._fields})
{k: getattr(r, k) for k in (
by if by is not None else StructResult._by)}
| {'struct_'+k: getattr(r, k) for k in (
fields if fields is not None else StructResult._fields)})
# find previous results?
if args.get('diff'):
@@ -607,10 +615,12 @@ if __name__ == "__main__":
namespace.sort.append((value, True if option == '-S' else False))
parser.add_argument(
'-s', '--sort',
nargs='?',
action=AppendSort,
help="Sort by this field.")
parser.add_argument(
'-S', '--reverse-sort',
nargs='?',
action=AppendSort,
help="Sort by this field, but backwards.")
parser.add_argument(
+15 -6
View File
@@ -339,6 +339,7 @@ def infer(results, *,
'__getattribute__': __getattribute__,
'_by': by,
'_fields': fields,
'_sort': fields,
'_types': types_,
})
@@ -419,8 +420,12 @@ def table(Result, results, diff_results=None, *,
reverse=True)
if sort:
for k, reverse in reversed(sort):
names.sort(key=lambda n: (getattr(table[n], k),)
if getattr(table.get(n), k, None) is not None else (),
names.sort(
key=lambda n: tuple(
(getattr(table[n], k),)
if getattr(table.get(n), k, None) is not None else ()
for k in ([k] if k else [
k for k in Result._sort if k in fields])),
reverse=reverse ^ (not k or k in Result._fields))
@@ -649,8 +654,10 @@ def main(csv_paths, *,
results.sort()
if sort:
for k, reverse in reversed(sort):
results.sort(key=lambda r: (getattr(r, k),)
if getattr(r, k) is not None else (),
results.sort(
key=lambda r: tuple(
(getattr(r, k),) if getattr(r, k) is not None else ()
for k in ([k] if k else Result._sort)),
reverse=reverse ^ (not k or k in Result._fields))
# write results to CSV
@@ -761,12 +768,14 @@ if __name__ == "__main__":
namespace.sort.append((value, True if option == '-S' else False))
parser.add_argument(
'-s', '--sort',
nargs='?',
action=AppendSort,
help="Sort by this fields.")
help="Sort by this field.")
parser.add_argument(
'-S', '--reverse-sort',
nargs='?',
action=AppendSort,
help="Sort by this fields, but backwards.")
help="Sort by this field, but backwards.")
parser.add_argument(
'-Y', '--summary',
action='store_true',