changeset 426:ed5ccd4cce49

performance: Quick and dirty profiling support for bake workers.
author Ludovic Chabant <ludovic@chabant.com>
date Fri, 26 Jun 2015 09:49:29 -0700
parents afeebdd9f767
children 3b658190c02b
files piecrust/baking/baker.py piecrust/baking/worker.py
diffstat 2 files changed, 24 insertions(+), 2 deletions(-) [+]
line wrap: on
line diff
--- a/piecrust/baking/baker.py	Thu Jun 25 14:51:37 2015 -0700
+++ b/piecrust/baking/baker.py	Fri Jun 26 09:49:29 2015 -0700
@@ -543,14 +543,20 @@
             logger.error("  " + e)
 
     def _createWorkerPool(self):
+        import sys
         from piecrust.baking.worker import BakeWorkerContext, worker_func
 
+        main_module = sys.modules['__main__']
+        is_profiling = os.path.basename(main_module.__file__) in [
+                'profile.py', 'cProfile.py']
+
         pool = _WorkerPool()
         for i in range(self.num_workers):
             ctx = BakeWorkerContext(
                     self.app.root_dir, self.app.cache.base_dir, self.out_dir,
                     pool.queue, pool.results, pool.abort_event,
-                    force=self.force, debug=self.app.debug)
+                    force=self.force, debug=self.app.debug,
+                    is_profiling=is_profiling)
             w = multiprocessing.Process(
                     name='BakeWorker_%d' % i,
                     target=worker_func, args=(i, ctx))
--- a/piecrust/baking/worker.py	Thu Jun 25 14:51:37 2015 -0700
+++ b/piecrust/baking/worker.py	Fri Jun 26 09:49:29 2015 -0700
@@ -13,6 +13,21 @@
 
 
 def worker_func(wid, ctx):
+    if ctx.is_profiling:
+        try:
+            import cProfile as profile
+        except ImportError:
+            import profile
+
+        ctx.is_profiling = False
+        profile.runctx('_real_worker_func(wid, ctx)',
+                       globals(), locals(),
+                       filename='BakeWorker-%d.prof' % wid)
+    else:
+        _real_worker_func(wid, ctx)
+
+
+def _real_worker_func(wid, ctx):
     logger.debug("Worker %d booting up..." % wid)
     w = BakeWorker(wid, ctx)
     w.run()
@@ -21,7 +36,7 @@
 class BakeWorkerContext(object):
     def __init__(self, root_dir, sub_cache_dir, out_dir,
                  work_queue, results, abort_event,
-                 force=False, debug=False):
+                 force=False, debug=False, is_profiling=False):
         self.root_dir = root_dir
         self.sub_cache_dir = sub_cache_dir
         self.out_dir = out_dir
@@ -30,6 +45,7 @@
         self.abort_event = abort_event
         self.force = force
         self.debug = debug
+        self.is_profiling = is_profiling
 
 
 JOB_LOAD, JOB_RENDER_FIRST, JOB_BAKE = range(0, 3)