-
Notifications
You must be signed in to change notification settings - Fork 99
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add performance tracking machinery #1509
Conversation
Thank you for your pull request! We could not find a changelog entry for this change. For details on how to document a change, see the contributing guide. |
Performance comparisonComparing Reporting top 10 highest non-negligible absolute total time differences for each session. Legend
Warnings (
|
i | Function | Base calls | Total calls | Body time (cumulative) | Body time (per call) | Total time (cumulative) | Total time (per call) |
---|---|---|---|---|---|---|---|
#1 | dataflow_plan_builder.py:139 :: build_plan |
1 (n.d.) | 1 (n.d.) | 0s (n.d.) | 0s (n.d.) | 1s - 0s = 1s (+97.987%) | 0s (n.d.) |
test_simple_manifest.py::test_simple_query_2
⚠️ ⚠️
Total time: 1s - 0s = 1s (+96.967%)
i | Function | Base calls | Total calls | Body time (cumulative) | Body time (per call) | Total time (cumulative) | Total time (per call) |
---|---|---|---|---|---|---|---|
#1 | dataflow_plan_builder.py:139 :: build_plan |
1 (n.d.) | 1 (n.d.) | 0s (n.d.) | 0s (n.d.) | 1s - 0s = 1s (+98.178%) | 0s (n.d.) |
metricflow-semantics/metricflow_semantics/test_helpers/performance_helpers.py
Outdated
Show resolved
Hide resolved
This commit adds the basic functionality needed for measuring performance. This includes: - classes to measure performance in different sessions using context managers - a context manager that can be used to instrument certain methods with performance tracking machinery - test fixtures for automatically generating reports using these classes
This commit adds `Comparison` classes which contain comparisons between performance measurements taken at two different points in time. It uses these classes in a new script that can be called to generate a markdown report of what changed regarding performance.
c7eb66b
to
cb61a7d
Compare
2584d73
to
e2493f6
Compare
e2493f6
to
f598cb0
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🎉
NOTE: I had to significantly refactor the original version of this PR to make it use cProfile, so I changed the description and comments to match.
Summary
This PR introduces some new testing functionality that we can use to avoid performance regressions. From a user perspective, the performance benchmarking workflow is:
tests_metricflow/performance/
that does something we want to track performance for. You can usemeasure_compilation_performance
fixtures to measure the compilation of some SQL based on a query spec and a manifest.make perf
to generate aperformance-report.json
.make perf-compare A=base-report.json B=other-report.json
to generate a Markdown file with a report on changes.The performance report
The
performance-report.json
file contains the "raw" data for a given run. It looks like this:Each "report" contains a list of "sessions". A session is a run where multiple measurements have been taken, i.e a pytest test. Each session contains a variety of "functions", which contain runtime statistics about each one of them.
Report comparison
I created a script called
compare_reports.py
which takes in two different reports files and calculates the difference between them (in absolute values and also percent). It then generates a markdown file calledperformance-comparison.md
with a nice little table like the one on my first comment.I added a
time.sleep(1)
tobuild_plan()
so that I could get a non-negligible result on the first comment.How it works
When you run
make perf
, themeasure_compilation_performance
fixture instantiates aPerformanceTracker
and yields a_measure()
function that will compile a query while running cProfile.The tests then all run, and at the end of it all the fixture compiles all reports by calling
perf_tracker.report_set
. This will return all the gatheredSessionReport
s. These reports contain all the data from all functions.After this, it writes the report to the JSON file.
Then, when you run⚠️ ) to the file.
make perf-compare
the script loads both the JSON files and uses thecompare()
methods in each of the report classes. These will generateComparison
classes with the percent and absolute differences. The script then renders these classes to markdown and writes it to a file. This script filters the comparisons to only show the top 10 most relevant comparisons, if their total runtime difference non-negligible (i.e the percent difference is higher than10e-7
). If any total runtime has increased by over 10%, it will add warnings (Next steps
Make a Github Actions bot that runs this on PRs to compare performance against
main
, and comments PRs with the generated markdown.