[Python-checkins] python/dist/src/Lib timeit.py,1.6,1.7

gvanrossum@users.sourceforge.net gvanrossum@users.sourceforge.net
Fri, 14 Mar 2003 09:21:06 -0800


Update of /cvsroot/python/python/dist/src/Lib
In directory sc8-pr-cvs1:/tmp/cvs-serv21199

Modified Files:
	timeit.py 
Log Message:
Implement some recommendations from Raymond H:

- Make all local variables in the template start with an underscore,
  to prevent name conflicts with the timed code.

- Added a method to print a traceback that shows source lines from the
  expanded template.

- Use that method in main().


Index: timeit.py
===================================================================
RCS file: /cvsroot/python/python/dist/src/Lib/timeit.py,v
retrieving revision 1.6
retrieving revision 1.7
diff -C2 -d -r1.6 -r1.7
*** timeit.py	7 Mar 2003 01:33:18 -0000	1.6
--- timeit.py	14 Mar 2003 17:21:00 -0000	1.7
***************
*** 59,62 ****
--- 59,63 ----
  __all__ = ["Timer"]
  
+ dummy_src_name = "<timeit-src>"
  default_number = 1000000
  default_repeat = 10
***************
*** 73,83 ****
  # being indented 8 spaces.
  template = """
! def inner(seq, timer):
      %(setup)s
!     t0 = timer()
!     for i in seq:
          %(stmt)s
!     t1 = timer()
!     return t1-t0
  """
  
--- 74,84 ----
  # being indented 8 spaces.
  template = """
! def inner(_seq, _timer):
      %(setup)s
!     _t0 = _timer()
!     for _i in _seq:
          %(stmt)s
!     _t1 = _timer()
!     return _t1 - _t0
  """
  
***************
*** 108,116 ****
          setup = reindent(setup, 4)
          src = template % {'stmt': stmt, 'setup': setup}
!         code = compile(src, "<src>", "exec")
          ns = {}
          exec code in globals(), ns
          self.inner = ns["inner"]
  
      def timeit(self, number=default_number):
          """Time 'number' executions of the main statement.
--- 109,142 ----
          setup = reindent(setup, 4)
          src = template % {'stmt': stmt, 'setup': setup}
!         self.src = src # Save for traceback display
!         code = compile(src, dummy_src_name, "exec")
          ns = {}
          exec code in globals(), ns
          self.inner = ns["inner"]
  
+     def print_exc(self, file=None):
+         """Helper to print a traceback from the timed code.
+ 
+         Typical use:
+ 
+             t = Timer(...)       # outside the try/except
+             try:
+                 t.timeit(...)    # or t.repeat(...)
+             except:
+                 t.print_exc()
+ 
+         The advantage over the standard traceback is that source lines
+         in the compiled template will be displayed.
+ 
+         The optional file argument directs where the traceback is
+         sent; it defaults to sys.stderr.
+         """
+         import linecache, traceback
+         linecache.cache[dummy_src_name] = (len(self.src),
+                                            None,
+                                            self.src.split("\n"),
+                                            dummy_src_name)
+         traceback.print_exc(file=file)
+ 
      def timeit(self, number=default_number):
          """Time 'number' executions of the main statement.
***************
*** 163,166 ****
--- 189,196 ----
      The return value is an exit code to be passed to sys.exit(); it
      may be None to indicate success.
+ 
+     When an exception happens during timing, a traceback is printed to
+     stderr and the return value is 1.  Exceptions at other times
+     (including the template compilation) are not caught.
      """
      if args is None:
***************
*** 202,216 ****
          for i in range(1, 10):
              number = 10**i
!             x = t.timeit(number)
              if x >= 0.2:
                  break
!     r = t.repeat(repeat, number)
      best = min(r)
      print "%d loops," % number,
      usec = best * 1e6 / number
      if repeat > 1:
!         print "best of %d: %.3f usec" % (repeat, usec)
      else:
!         print "time: %.3f usec" % usec
      return None
  
--- 232,254 ----
          for i in range(1, 10):
              number = 10**i
!             try:
!                 x = t.timeit(number)
!             except:
!                 t.print_exc()
!                 return 1
              if x >= 0.2:
                  break
!     try:
!         r = t.repeat(repeat, number)
!     except:
!         t.print_exc()
!         return 1
      best = min(r)
      print "%d loops," % number,
      usec = best * 1e6 / number
      if repeat > 1:
!         print "best of %d: %.3f usec per loop" % (repeat, usec)
      else:
!         print "time: %.3f usec per loop" % usec
      return None