From b63bfc83d8495a6358d042381c5777f1c5c9bcc3 Mon Sep 17 00:00:00 2001 From: evandrocoan Date: Sun, 3 May 2020 19:47:03 -0300 Subject: [PATCH 1/3] Created the --benchmark command line option https://anki.tenderapp.com/discussions/ankidesktop/41106-card-audio-playback-changes-bug-in-212x Based on the snippet: https://gist.github.com/evandrocoan/961d46e10424e53ba8946fac66e0efac --- qt/aqt/__init__.py | 35 +++++++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) diff --git a/qt/aqt/__init__.py b/qt/aqt/__init__.py index b7183af15..5637c69fe 100644 --- a/qt/aqt/__init__.py +++ b/qt/aqt/__init__.py @@ -308,6 +308,13 @@ def parseArgs(argv): parser.add_argument("-b", "--base", help="path to base folder", default="") parser.add_argument("-p", "--profile", help="profile name to load", default="") parser.add_argument("-l", "--lang", help="interface language (en, de, etc)") + parser.add_argument( + "-bm", + "--benchmark", + type=int, + help="reports anki run time performance to stdout (pass the number of characters to report)", + default=None, + ) return parser.parse_known_args(argv[1:]) @@ -347,6 +354,21 @@ def setupGL(pm): os.environ["QT_OPENGL"] = mode +def printBenchmark(argumentsNamespace, profiller): + if argumentsNamespace.benchmark and profiller: + import io + import pstats + + profiller.disable() + outputstream = io.StringIO() + profiller_status = pstats.Stats(profiller, stream=outputstream) + profiller_status.sort_stats("time") + profiller_status.print_stats() + sys.stderr.write( + f"\n{outputstream.getvalue()[:argumentsNamespace.benchmark]}\n" + ) + + def run(): try: _run() @@ -370,6 +392,7 @@ def _run(argv=None, exec=True): If no 'argv' is supplied then 'sys.argv' will be used. """ global mw + profiller = None if argv is None: argv = sys.argv @@ -377,6 +400,12 @@ def _run(argv=None, exec=True): # parse args opts, args = parseArgs(argv) + if opts.benchmark: + import cProfile + + profiller = cProfile.Profile() + profiller.enable() + # profile manager pm = None try: @@ -409,6 +438,7 @@ def _run(argv=None, exec=True): app = AnkiApp(argv) if app.secondInstance(): # we've signaled the primary instance, so we should close + printBenchmark(opts, profiller) return if not pm: @@ -419,6 +449,7 @@ def _run(argv=None, exec=True): Anki could not create its data folder. Please see the File Locations \ section of the manual, and ensure that location is not read-only.""", ) + printBenchmark(opts, profiller) return # disable icons on mac; this must be done before window created @@ -452,6 +483,7 @@ section of the manual, and ensure that location is not read-only.""", No usable temporary folder found. Make sure C:\\temp exists or TEMP in your \ environment points to a valid, writable folder.""", ) + printBenchmark(opts, profiller) return if pmLoadResult.firstTime: @@ -490,4 +522,7 @@ environment points to a valid, writable folder.""", if exec: app.exec() else: + printBenchmark(opts, profiller) return app + + printBenchmark(opts, profiller) From 2e11a596aa4bb7ee4f6e68cb5a2e13a10fc444c4 Mon Sep 17 00:00:00 2001 From: evandrocoan Date: Mon, 4 May 2020 23:15:23 -0300 Subject: [PATCH 2/3] Fixed profiler word misspelling and stopped trimming the output --- qt/aqt/__init__.py | 32 +++++++++++++++----------------- 1 file changed, 15 insertions(+), 17 deletions(-) diff --git a/qt/aqt/__init__.py b/qt/aqt/__init__.py index 5637c69fe..1c440c726 100644 --- a/qt/aqt/__init__.py +++ b/qt/aqt/__init__.py @@ -354,19 +354,17 @@ def setupGL(pm): os.environ["QT_OPENGL"] = mode -def printBenchmark(argumentsNamespace, profiller): - if argumentsNamespace.benchmark and profiller: +def printBenchmark(argumentsNamespace, profiler): + if argumentsNamespace.benchmark and profiler: import io import pstats - profiller.disable() + profiler.disable() outputstream = io.StringIO() - profiller_status = pstats.Stats(profiller, stream=outputstream) - profiller_status.sort_stats("time") - profiller_status.print_stats() - sys.stderr.write( - f"\n{outputstream.getvalue()[:argumentsNamespace.benchmark]}\n" - ) + profiler_status = pstats.Stats(profiler, stream=outputstream) + profiler_status.sort_stats("time") + profiler_status.print_stats() + sys.stderr.write(f"\n{outputstream.getvalue()}\n") def run(): @@ -392,7 +390,7 @@ def _run(argv=None, exec=True): If no 'argv' is supplied then 'sys.argv' will be used. """ global mw - profiller = None + profiler = None if argv is None: argv = sys.argv @@ -403,8 +401,8 @@ def _run(argv=None, exec=True): if opts.benchmark: import cProfile - profiller = cProfile.Profile() - profiller.enable() + profiler = cProfile.Profile() + profiler.enable() # profile manager pm = None @@ -438,7 +436,7 @@ def _run(argv=None, exec=True): app = AnkiApp(argv) if app.secondInstance(): # we've signaled the primary instance, so we should close - printBenchmark(opts, profiller) + printBenchmark(opts, profiler) return if not pm: @@ -449,7 +447,7 @@ def _run(argv=None, exec=True): Anki could not create its data folder. Please see the File Locations \ section of the manual, and ensure that location is not read-only.""", ) - printBenchmark(opts, profiller) + printBenchmark(opts, profiler) return # disable icons on mac; this must be done before window created @@ -483,7 +481,7 @@ section of the manual, and ensure that location is not read-only.""", No usable temporary folder found. Make sure C:\\temp exists or TEMP in your \ environment points to a valid, writable folder.""", ) - printBenchmark(opts, profiller) + printBenchmark(opts, profiler) return if pmLoadResult.firstTime: @@ -522,7 +520,7 @@ environment points to a valid, writable folder.""", if exec: app.exec() else: - printBenchmark(opts, profiller) + printBenchmark(opts, profiler) return app - printBenchmark(opts, profiller) + printBenchmark(opts, profiler) From 338e904bd41e61ffadfdb510d0918896198e0d45 Mon Sep 17 00:00:00 2001 From: evandrocoan Date: Mon, 4 May 2020 23:29:48 -0300 Subject: [PATCH 3/3] Created the ANKI_RUN_BENCHMARK environment variable replacing the command line argument. --- qt/aqt/__init__.py | 24 ++++++++---------------- 1 file changed, 8 insertions(+), 16 deletions(-) diff --git a/qt/aqt/__init__.py b/qt/aqt/__init__.py index 1c440c726..82d7d1060 100644 --- a/qt/aqt/__init__.py +++ b/qt/aqt/__init__.py @@ -35,6 +35,7 @@ appHelpSite = HELP_SITE from aqt.main import AnkiQt # isort:skip from aqt.profiles import ProfileManager # isort:skip +profiler = None mw: Optional[AnkiQt] = None # set on init moduleDir = os.path.split(os.path.dirname(os.path.abspath(__file__)))[0] @@ -308,13 +309,6 @@ def parseArgs(argv): parser.add_argument("-b", "--base", help="path to base folder", default="") parser.add_argument("-p", "--profile", help="profile name to load", default="") parser.add_argument("-l", "--lang", help="interface language (en, de, etc)") - parser.add_argument( - "-bm", - "--benchmark", - type=int, - help="reports anki run time performance to stdout (pass the number of characters to report)", - default=None, - ) return parser.parse_known_args(argv[1:]) @@ -354,8 +348,8 @@ def setupGL(pm): os.environ["QT_OPENGL"] = mode -def printBenchmark(argumentsNamespace, profiler): - if argumentsNamespace.benchmark and profiler: +def printBenchmark(): + if os.environ.get("ANKI_RUN_BENCHMARK"): import io import pstats @@ -390,7 +384,7 @@ def _run(argv=None, exec=True): If no 'argv' is supplied then 'sys.argv' will be used. """ global mw - profiler = None + global profiler if argv is None: argv = sys.argv @@ -398,7 +392,7 @@ def _run(argv=None, exec=True): # parse args opts, args = parseArgs(argv) - if opts.benchmark: + if os.environ.get("ANKI_RUN_BENCHMARK"): import cProfile profiler = cProfile.Profile() @@ -436,7 +430,6 @@ def _run(argv=None, exec=True): app = AnkiApp(argv) if app.secondInstance(): # we've signaled the primary instance, so we should close - printBenchmark(opts, profiler) return if not pm: @@ -447,7 +440,7 @@ def _run(argv=None, exec=True): Anki could not create its data folder. Please see the File Locations \ section of the manual, and ensure that location is not read-only.""", ) - printBenchmark(opts, profiler) + printBenchmark() return # disable icons on mac; this must be done before window created @@ -481,7 +474,7 @@ section of the manual, and ensure that location is not read-only.""", No usable temporary folder found. Make sure C:\\temp exists or TEMP in your \ environment points to a valid, writable folder.""", ) - printBenchmark(opts, profiler) + printBenchmark() return if pmLoadResult.firstTime: @@ -520,7 +513,6 @@ environment points to a valid, writable folder.""", if exec: app.exec() else: - printBenchmark(opts, profiler) return app - printBenchmark(opts, profiler) + printBenchmark()