diff --git a/docs/development.md b/docs/development.md index 325e25dfd..2319322f1 100644 --- a/docs/development.md +++ b/docs/development.md @@ -210,6 +210,8 @@ If TRACESQL is set, all sql statements will be printed as they are executed. If LOGTERM is set before starting Anki, warnings and error messages that are normally placed in the collection2.log file will also be printed on stdout. +If ANKI_PROFILE_CODE is set, Python profiling data will be written on exit. + ## Cleaning Unlike the old Make system, a "clean build" should almost never be required diff --git a/pip/requirements.in b/pip/requirements.in index ebf4183de..aeb852182 100644 --- a/pip/requirements.in +++ b/pip/requirements.in @@ -17,6 +17,7 @@ pylint pytest requests[socks] send2trash +snakeviz stringcase waitress fluent-syntax diff --git a/qt/BUILD.bazel b/qt/BUILD.bazel index e9900f562..c48586ba5 100644 --- a/qt/BUILD.bazel +++ b/qt/BUILD.bazel @@ -128,3 +128,12 @@ py_binary( "//qt/aqt:aqt_with_data", ], ) + +py_binary( + name = "profile", + srcs = ["tools/profile.py"], + tags = ["manual"], + deps = [ + requirement("snakeviz"), + ], +) diff --git a/qt/aqt/__init__.py b/qt/aqt/__init__.py index 3516d95fd..37a580654 100644 --- a/qt/aqt/__init__.py +++ b/qt/aqt/__init__.py @@ -392,6 +392,7 @@ def write_profile_results(): profiler.disable() profiler.dump_stats("anki.prof") print("profile stats written to anki.prof") + print("use 'bazel run qt:profile' to explore") def run(): diff --git a/qt/tools/profile.py b/qt/tools/profile.py new file mode 100755 index 000000000..99b1376f4 --- /dev/null +++ b/qt/tools/profile.py @@ -0,0 +1,8 @@ +import sys, os +import snakeviz + +from snakeviz.cli import main + +profile = os.path.join(os.environ["BUILD_WORKSPACE_DIRECTORY"], "anki.prof") +sys.argv.append(profile) +sys.exit(main())