Skip to content

Commit d9d4da7

Browse files
committed
Write benchmarking and profiling outputs to files and upload artifact in gh-action.
1 parent 9464f4f commit d9d4da7

File tree

4 files changed

+54
-27
lines changed

4 files changed

+54
-27
lines changed

.github/workflows/main.yml

+8
Original file line numberDiff line numberDiff line change
@@ -112,6 +112,10 @@ jobs:
112112
pip install tox tox-gh-actions
113113
- name: Run profiling
114114
run: tox run -e profiling
115+
- uses: actions/upload-artifact@v4
116+
with:
117+
name: upload-benchmarking-results
118+
path: ${GITHUB_WORKSPACE}/.tox/profiling/log
115119

116120
benchmarks:
117121
runs-on: ubuntu-22.04
@@ -127,6 +131,10 @@ jobs:
127131
pip install tox tox-gh-actions
128132
- name: Run benchmarks
129133
run: tox run -e benchmarks
134+
- uses: actions/upload-artifact@v4
135+
with:
136+
name: upload-benchmarking-results
137+
path: ${GITHUB_WORKSPACE}/.tox/benchmarks/log
130138

131139
publish:
132140
if: ${{ false }} # disabled until decided when it should run exactly

benchmarks/benchmark_all_examples.py

+34-26
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import os
12
import runpy
23
import sys
34
from io import StringIO
@@ -10,30 +11,37 @@
1011

1112
from benchmarks.benchmark_utils import swap_attr
1213

13-
for entry in [entry for entry in importlib_resources.contents('examples') if
14-
not pkg_resources.resource_isdir('examples', entry)
15-
and entry.endswith(".py")
16-
and '__init__' not in entry
17-
and 'DELETE' not in entry
18-
]:
19-
print("*****************************************************************")
20-
print("Benchmarking {}".format(entry))
21-
print("*****************************************************************")
14+
if __name__ == '__main__':
2215

23-
with path('examples', entry) as file_in:
24-
with Benchmarker(cycle=20, extra=1) as bench:
25-
@bench(entry)
26-
def _(_):
27-
# prevent Benchmarker from doing "ZeroDivisionError: float division by zero:
28-
# ratio = base_time / real_time"
29-
sleep(0.001)
30-
# In order to pipe input into examples that have input(),
31-
# we use the test package, which is meant for internal use by Python only internal and
32-
# Any use of this package outside of Python’s standard library is discouraged as code (..)
33-
# can change or be removed without notice between releases of Python.
34-
# https://docs.python.org/3/library/test.html
35-
# TODO remove input() from examples?
36-
with swap_attr(sys, "stdin", StringIO("q")):
37-
runpy.run_path(file_in, run_name="__main__", init_globals={
38-
'argv': ['--sleep-for-animation=False', '--do_rendering=False']
39-
})
16+
for entry in [entry for entry in importlib_resources.contents('examples') if
17+
not pkg_resources.resource_isdir('examples', entry)
18+
and entry.endswith(".py")
19+
and '__init__' not in entry
20+
and 'DELETE' not in entry
21+
]:
22+
print("*****************************************************************")
23+
print("Benchmarking {}".format(entry))
24+
print("*****************************************************************")
25+
26+
benchmarks_output_folder = os.environ.get('BENCHMARKS_OUTPUT_FOLDER', None)
27+
outfile = None
28+
if benchmarks_output_folder:
29+
outfile = os.path.join(benchmarks_output_folder, f"{entry}.json")
30+
31+
with path('examples', entry) as file_in:
32+
with Benchmarker(cycle=20, extra=1, outfile=outfile) as bench:
33+
@bench(entry)
34+
def _(_):
35+
# prevent Benchmarker from doing "ZeroDivisionError: float division by zero:
36+
# ratio = base_time / real_time"
37+
sleep(0.001)
38+
# In order to pipe input into examples that have input(),
39+
# we use the test package, which is meant for internal use by Python only internal and
40+
# Any use of this package outside of Python’s standard library is discouraged as code (..)
41+
# can change or be removed without notice between releases of Python.
42+
# https://docs.python.org/3/library/test.html
43+
# TODO remove input() from examples?
44+
with swap_attr(sys, "stdin", StringIO("q")):
45+
runpy.run_path(file_in, run_name="__main__", init_globals={
46+
'argv': ['--sleep-for-animation=False', '--do_rendering=False']
47+
})

benchmarks/profile_all_examples.py

+8-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
import cProfile
2+
import os
23
import runpy
34
import sys
5+
from fileinput import filename
46
from io import StringIO
57

68
import importlib_resources
@@ -16,14 +18,19 @@ def profile(resource, entry):
1618
print("*****************************************************************")
1719
print("Profiling {}".format(entry))
1820
print("*****************************************************************")
21+
profiling_output_folder = os.environ.get('PROFILING_OUTPUT_FOLDER', None)
22+
outfile = None
23+
if profiling_output_folder:
24+
outfile = os.path.join(profiling_output_folder, f"{entry}.prof")
25+
1926
with swap_attr(sys, "stdin", StringIO("q")):
2027
global my_func
2128

2229
def my_func(): runpy.run_path(file_in, run_name="__main__", init_globals={
2330
'argv': ['--sleep-for-animation=False', '--do_rendering=False']
2431
})
2532

26-
cProfile.run('my_func()', sort='time')
33+
cProfile.run('my_func()', sort='time', filename=outfile)
2734

2835

2936
for entry in [entry for entry in importlib_resources.contents('examples') if

tox.ini

+4
Original file line numberDiff line numberDiff line change
@@ -71,13 +71,17 @@ commands =
7171
base_python = python3.10
7272
deps =
7373
-r requirements-dev.txt
74+
set_env =
75+
BENCHMARKS_OUTPUT_FOLDER = {work_dir}/{env_name}/log
7476
commands =
7577
python benchmarks/benchmark_all_examples.py
7678

7779
[testenv:profiling]
7880
base_python = python3.10
7981
deps =
8082
-r requirements-dev.txt
83+
set_env =
84+
PROFILING_OUTPUT_FOLDER = {work_dir}/{env_name}/log
8185
commands =
8286
python benchmarks/profile_all_examples.py
8387

0 commit comments

Comments
 (0)