Ned Batchelder committed 0b8dc7f

Some per-instance caching to speed code parsing and analysis.

Comments (0)

Files changed (2)

     return ret
+def expensive(fn):
+    """A decorator to cache the result of an expensive operation.
+    Only applies to methods with no arguments.
+    """
+    attr = "_cache_" + fn.__name__
+    def _wrapped(self):
+        if not hasattr(self, attr):
+            setattr(self, attr, fn(self))
+        return getattr(self, attr)
+    return _wrapped
 class CoverageException(Exception):
     """An exception specific to Coverage."""


 from coverage.backward import set, sorted, StringIO # pylint: disable-msg=W0622
 from coverage.bytecode import ByteCodes, CodeObjects
-from coverage.misc import nice_pair, CoverageException, NoSource
+from coverage.misc import nice_pair, CoverageException, NoSource, expensive
 class CodeParser(object):
             if fl1 != fl2:
                 all_arcs.append((fl1, fl2))
         return sorted(all_arcs)
+    arcs = expensive(arcs)
     def exit_counts(self):
         """Get a mapping from line numbers to count of exits from that line.
             exit_counts[l1] += 1
         return exit_counts
+    exit_counts = expensive(exit_counts)
 ## Opcodes that guide the ByteParser.