]> git.ipfire.org Git - thirdparty/sqlalchemy/sqlalchemy.git/commitdiff
Updates for examples/performance
authorMike Bayer <mike_mp@zzzcomputing.com>
Tue, 26 May 2020 03:24:05 +0000 (23:24 -0400)
committerMike Bayer <mike_mp@zzzcomputing.com>
Tue, 26 May 2020 03:24:05 +0000 (23:24 -0400)
added --sort option and also --raw option
from 6b3513f56c2a5d3ba45215b2438c47dba4336740

Change-Id: I42ef2135db08c87f33b51faed9c8bbff510c9e9b

doc/build/changelog/unreleased_13/perf_suite.rst [new file with mode: 0644]
examples/performance/__init__.py

diff --git a/doc/build/changelog/unreleased_13/perf_suite.rst b/doc/build/changelog/unreleased_13/perf_suite.rst
new file mode 100644 (file)
index 0000000..f928cd3
--- /dev/null
@@ -0,0 +1,7 @@
+.. change::
+    :tags: change, examples
+
+    Added new option ``--raw`` to the examples.performance suite
+    which will dump the raw profile test for consumption by any
+    number of profiling visualizer tools.   Removed the "runsnake"
+    option as runsnake is very hard to build at this point;
index c6244554fab15ff04f8547315bd3e29a7e333dcb..f4f53f0d508a392e270db2b1d69503d35da3c488 100644 (file)
@@ -107,15 +107,6 @@ individual tests::
 
         ...
 
-Using RunSnake
---------------
-
-This option requires the `RunSnake <https://pypi.python.org/pypi/RunSnakeRun>`_
-command line tool be installed::
-
-    $ python -m examples.performance single_inserts --test test_core --num 1000 --runsnake
-
-A graphical RunSnake output will be displayed.
 
 .. _examples_profiling_writeyourown:
 
@@ -213,9 +204,6 @@ We can run our new script directly::
     test_joinedload : load everything, joined eager loading. (1000 iterations); total time 2.754592 sec
     test_subqueryload : load everything, subquery eager loading. (1000 iterations); total time 2.977696 sec
 
-As well as see RunSnake output for an individual test::
-
-    $ python test_loads.py  --num 100 --runsnake --test test_joinedload
 
 """  # noqa
 import argparse
@@ -238,12 +226,13 @@ class Profiler(object):
     def __init__(self, options):
         self.test = options.test
         self.dburl = options.dburl
-        self.runsnake = options.runsnake
         self.profile = options.profile
         self.dump = options.dump
+        self.raw = options.raw
         self.callers = options.callers
         self.num = options.num
         self.echo = options.echo
+        self.sort = options.sort
         self.stats = []
 
     @classmethod
@@ -292,7 +281,7 @@ class Profiler(object):
             self._run_test(test)
             self.stats[-1].report()
 
-    def _run_with_profile(self, fn):
+    def _run_with_profile(self, fn, sort):
         pr = cProfile.Profile()
         pr.enable()
         try:
@@ -300,9 +289,9 @@ class Profiler(object):
         finally:
             pr.disable()
 
-        stats = pstats.Stats(pr).sort_stats("cumulative")
+        stats = pstats.Stats(pr)
 
-        self.stats.append(TestResult(self, fn, stats=stats))
+        self.stats.append(TestResult(self, fn, stats=stats, sort=sort))
         return result
 
     def _run_with_time(self, fn):
@@ -316,8 +305,8 @@ class Profiler(object):
     def _run_test(self, fn):
         if self._setup:
             self._setup(self.dburl, self.echo, self.num)
-        if self.profile or self.runsnake or self.dump:
-            self._run_with_profile(fn)
+        if self.profile or self.dump:
+            self._run_with_profile(fn, self.sort)
         else:
             self._run_with_time(fn)
 
@@ -358,20 +347,26 @@ class Profiler(object):
             action="store_true",
             help="run profiling and dump call counts",
         )
+        parser.add_argument(
+            "--sort",
+            type=str,
+            default="cumulative",
+            help="profiling sort, defaults to cumulative",
+        )
         parser.add_argument(
             "--dump",
             action="store_true",
             help="dump full call profile (implies --profile)",
         )
         parser.add_argument(
-            "--callers",
-            action="store_true",
-            help="print callers as well (implies --dump)",
+            "--raw",
+            type=str,
+            help="dump raw profile data to file (implies --profile)",
         )
         parser.add_argument(
-            "--runsnake",
+            "--callers",
             action="store_true",
-            help="invoke runsnakerun (implies --profile)",
+            help="print callers as well (implies --dump)",
         )
         parser.add_argument(
             "--echo", action="store_true", help="Echo SQL output"
@@ -379,7 +374,7 @@ class Profiler(object):
         args = parser.parse_args()
 
         args.dump = args.dump or args.callers
-        args.profile = args.profile or args.dump or args.runsnake
+        args.profile = args.profile or args.dump or args.raw
 
         if cls.name is None:
             __import__(__name__ + "." + args.name)
@@ -397,11 +392,14 @@ class Profiler(object):
 
 
 class TestResult(object):
-    def __init__(self, profile, test, stats=None, total_time=None):
+    def __init__(
+        self, profile, test, stats=None, total_time=None, sort="cumulative"
+    ):
         self.profile = profile
         self.test = test
         self.stats = stats
         self.total_time = total_time
+        self.sort = sort
 
     def report(self):
         print(self._summary())
@@ -421,17 +419,20 @@ class TestResult(object):
         return summary
 
     def report_stats(self):
-        if self.profile.runsnake:
-            self._runsnake()
-        elif self.profile.dump:
-            self._dump()
+        if self.profile.dump:
+            self._dump(self.sort)
+        elif self.profile.raw:
+            self._dump_raw()
 
-    def _dump(self):
-        self.stats.sort_stats("time", "calls")
+    def _dump(self, sort):
+        self.stats.sort_stats(*re.split(r"[ ,]", self.sort))
         self.stats.print_stats()
         if self.profile.callers:
             self.stats.print_callers()
 
+    def _dump_raw(self):
+        self.stats.dump_stats(self.profile.raw)
+
     def _runsnake(self):
         filename = "%s.profile" % self.test.__name__
         try: