Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit ca6476a

Browse files
committed
Generate html benchmark report
1 parent 991e568 commit ca6476a

File tree

11 files changed

+266
-2
lines changed

11 files changed

+266
-2
lines changed

.github/workflows/invoke-ci-cxx17.yml

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,15 @@ jobs:
9999
run: |
100100
cmake --build . --target benchmark --config ${{ matrix.build_type }}
101101
102+
- name: Upload benchmark report
103+
if: ${{ matrix.build_type == 'Debug' && matrix.config.generator == 'Ninja' }}
104+
uses: actions/upload-artifact@v2
105+
with:
106+
name: benchmark report - ${{ matrix.config.name }}
107+
path: |
108+
build/benchmark/benchmark.*.json
109+
build/benchmark/reports/
110+
102111
- name: Test
103112
working-directory: build
104113
run: |

.github/workflows/invoke-ci-cxx20.yml

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,15 @@ jobs:
9999
run: |
100100
cmake --build . --target benchmark --config ${{ matrix.build_type }}
101101
102+
- name: Upload benchmark report
103+
if: ${{ matrix.build_type == 'Debug' && matrix.config.generator == 'Ninja' }}
104+
uses: actions/upload-artifact@v2
105+
with:
106+
name: benchmark report - ${{ matrix.config.name }}
107+
path: |
108+
build/benchmark/benchmark.*.json
109+
build/benchmark/reports/
110+
102111
- name: Test
103112
working-directory: build
104113
run: |

benchmark/CMakeLists.txt

Lines changed: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,12 +25,15 @@ endif()
2525
function(add_benchmark NAME INPUT)
2626
cmake_parse_arguments("ARG"
2727
""
28-
"INSTANTIATIONS"
28+
"INSTANTIATIONS;OUTPUT;REPORT_TEMPLATE"
2929
"CASES"
3030
${ARGN})
3131
if (NOT DEFINED ARG_INSTANTIATIONS)
3232
set(ARG_INSTANTIATIONS 10000)
3333
endif()
34+
if (NOT DEFINED ARG_OUTPUT)
35+
set(ARG_OUTPUT ${NAME}.html)
36+
endif()
3437

3538
set(_instantiations "")
3639
foreach(_i RANGE 1 ${ARG_INSTANTIATIONS})
@@ -89,6 +92,25 @@ void benchmark${_benchmark}() {${_instantiations}\n}
8992
--instantiations=${ARG_INSTANTIATIONS}
9093
--object=<OBJECT>
9194
--)
95+
96+
get_filename_component(INPUT ${INPUT} ABSOLUTE)
97+
get_filename_component(ARG_REPORT_TEMPLATE ${ARG_REPORT_TEMPLATE} ABSOLUTE)
98+
get_filename_component(ARG_OUTPUT ${ARG_OUTPUT} ABSOLUTE
99+
BASE_DIR ${CMAKE_CURRENT_BINARY_DIR})
100+
add_custom_command(
101+
OUTPUT ${ARG_OUTPUT}
102+
COMMAND ${Python3_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/generate_report.py
103+
--target=${NAME}
104+
--source=${INPUT}
105+
--instantiations=${ARG_INSTANTIATIONS}
106+
--output=${ARG_OUTPUT}
107+
--template=${ARG_REPORT_TEMPLATE}
108+
--objects="$<TARGET_OBJECTS:${NAME}>"
109+
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
110+
DEPENDS ${NAME} ${ARG_REPORT_TEMPLATE} $<TARGET_OBJECTS:${NAME}>)
111+
112+
add_custom_target(${NAME}.report DEPENDS ${ARG_OUTPUT})
113+
set_property(TARGET ${NAME}.report PROPERTY FOLDER "benchmark/report")
92114
endif()
93115
endfunction()
94116

@@ -103,6 +125,8 @@ set_property(TARGET benchmark PROPERTY FOLDER "benchmark")
103125

104126
foreach(_benchmark ${_benchmarks})
105127
add_benchmark(benchmark.${_benchmark} ${_benchmark}.cpp.in
128+
REPORT_TEMPLATE template/report.html.in
129+
OUTPUT reports/${_benchmark}.html
106130
CASES
107131
1 "plain call"
108132
2 "std::invoke"
@@ -111,4 +135,7 @@ foreach(_benchmark ${_benchmarks})
111135
set_property(TARGET benchmark.${_benchmark} PROPERTY FOLDER "benchmark")
112136

113137
add_dependencies(benchmark benchmark.${_benchmark})
138+
if (_benchmark_report)
139+
add_dependencies(benchmark benchmark.${_benchmark}.report)
140+
endif()
114141
endforeach()

benchmark/compiler_launcher.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -133,7 +133,7 @@
133133
'benchmark': int(benchmark),
134134
'label': label,
135135
'compilation_time': compilation_time,
136-
'memory_usage': memory_usage,
136+
'memory_usage': memory_usage * 1024 if memory_usage != '-' else '-',
137137
'object_size': object_size,
138138
}
139139
with open(args.object + '.benchmark.json', 'w') as file:

benchmark/generate_report.py

Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
# Eggs.Invoke
2+
#
3+
# Copyright Agustin K-ballo Berge, Fusion Fenix 2020
4+
#
5+
# Distributed under the Boost Software License, Version 1.0. (See accompanying
6+
# file LICENSE.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
7+
import argparse
8+
import html
9+
import json
10+
import os
11+
import re
12+
13+
# ${Python3_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/generate_report.py
14+
# --target=${NAME}
15+
# --source=${INPUT}
16+
# --instantiations=${ARG_INSTANTIATIONS}
17+
# --output=${OUTPUT}
18+
# --template=${ARG_REPORT_TEMPLATE}
19+
# --objects="$<TARGET_OBJECTS:${NAME}>"
20+
if __name__ == '__main__':
21+
parser = argparse.ArgumentParser()
22+
parser.add_argument('--target', required=True)
23+
parser.add_argument('--source', required=True)
24+
parser.add_argument('--instantiations', required=True)
25+
parser.add_argument('--output', required=True)
26+
parser.add_argument('--template', required=True)
27+
parser.add_argument('--objects', required=True)
28+
args = parser.parse_args()
29+
30+
reports = []
31+
for object in args.objects.split(';'):
32+
with open(object + '.benchmark.json', 'r') as file:
33+
report = json.load(file)
34+
del report['target']
35+
36+
if (report['benchmark'] == 0):
37+
baseline = report
38+
else:
39+
reports.append(report)
40+
41+
datum = sorted(reports, key=lambda x: x['benchmark'])
42+
DATUM = json.dumps({ 'values' : reports }, indent=2)
43+
44+
compilation_time = {
45+
'field': 'compilation_time',
46+
'key': 'Compilation time',
47+
'baseline': baseline['compilation_time'],
48+
'format': ',.2f',
49+
'unit': 's'
50+
}
51+
memory_usage = {
52+
'field': 'memory_usage',
53+
'key': 'Memory usage',
54+
'baseline': baseline['memory_usage'],
55+
'format': '.5s',
56+
'unit': 'B'
57+
}
58+
object_size = {
59+
'field': 'object_size',
60+
'key': 'Object size',
61+
'baseline': baseline['object_size'],
62+
'format': '.5s',
63+
'unit': 'B'
64+
}
65+
aspects = [compilation_time, memory_usage, object_size]
66+
ASPECTS = json.dumps(aspects, indent=2)
67+
68+
with open(args.target + '.json', 'w') as file:
69+
json.dump({ 'aspects': aspects, 'values': reports }, file)
70+
71+
with open(args.source, 'r') as file:
72+
source = file.read()
73+
source = source.replace('@BENCHMARK_INSTANTIATIONS@', '').rstrip()
74+
SOURCE_CODE = html.escape(source)
75+
76+
INSTANTIATIONS = args.instantiations;
77+
78+
template_dir = os.path.dirname(args.template)
79+
def INCLUDE(path):
80+
path = os.path.join(template_dir, path)
81+
with open(path, 'r') as file:
82+
return file.read()
83+
84+
with open(args.template, 'r') as file:
85+
template = file.read()
86+
output = re.sub(r'@(.*)@', lambda m: str(eval(m.group(1))), template)
87+
with open(args.output, 'w') as file:
88+
file.write(output)

benchmark/template/d3.min.js

Lines changed: 5 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

benchmark/template/nv.d3.min.css

Lines changed: 2 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

benchmark/template/nv.d3.min.js

Lines changed: 11 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

benchmark/template/prism.min.css

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)