[Python-checkins] cpython: Issue #18983: Allow selection of output units in timeit.

robert.collins python-checkins at python.org
Tue Mar 17 21:55:06 CET 2015


https://hg.python.org/cpython/rev/1ebf8d5b7d60
changeset:   95021:1ebf8d5b7d60
user:        Robert Collins <rbtcollins at hp.com>
date:        Wed Mar 18 09:54:50 2015 +1300
summary:
  Issue #18983: Allow selection of output units in timeit.

This allows manual selection of a specific unit such as usecs rather than the
use of a heuristic. This is intended to aid machine processing of timeit
output.

Patch by Serhiy Storchaka.

files:
  Doc/library/timeit.rst  |   8 +++++-
  Lib/test/test_timeit.py |  20 +++++++++++++++++
  Lib/timeit.py           |  34 +++++++++++++++++++++-------
  Misc/NEWS               |   3 ++
  4 files changed, 55 insertions(+), 10 deletions(-)


diff --git a/Doc/library/timeit.rst b/Doc/library/timeit.rst
--- a/Doc/library/timeit.rst
+++ b/Doc/library/timeit.rst
@@ -179,7 +179,7 @@
 
 When called as a program from the command line, the following form is used::
 
-   python -m timeit [-n N] [-r N] [-s S] [-t] [-c] [-h] [statement ...]
+   python -m timeit [-n N] [-r N] [-u U] [-s S] [-t] [-c] [-h] [statement ...]
 
 Where the following options are understood:
 
@@ -208,6 +208,12 @@
 
    use :func:`time.time` (deprecated)
 
+.. cmdoption:: -u, --unit=U
+
+    specify a time unit for timer output; can select usec, msec, or sec
+
+   .. versionadded:: 3.5
+
 .. cmdoption:: -c, --clock
 
    use :func:`time.clock` (deprecated)
diff --git a/Lib/test/test_timeit.py b/Lib/test/test_timeit.py
--- a/Lib/test/test_timeit.py
+++ b/Lib/test/test_timeit.py
@@ -312,6 +312,26 @@
                 10000 loops, best of 3: 50 usec per loop
             """))
 
+    def test_main_with_time_unit(self):
+        unit_sec = self.run_main(seconds_per_increment=0.002,
+                switches=['-u', 'sec'])
+        self.assertEqual(unit_sec,
+                "1000 loops, best of 3: 0.002 sec per loop\n")
+        unit_msec = self.run_main(seconds_per_increment=0.002,
+                switches=['-u', 'msec'])
+        self.assertEqual(unit_msec,
+                "1000 loops, best of 3: 2 msec per loop\n")
+        unit_usec = self.run_main(seconds_per_increment=0.002,
+                switches=['-u', 'usec'])
+        self.assertEqual(unit_usec,
+                "1000 loops, best of 3: 2e+03 usec per loop\n")
+        # Test invalid unit input
+        with captured_stderr() as error_stringio:
+            invalid = self.run_main(seconds_per_increment=0.002,
+                    switches=['-u', 'parsec'])
+        self.assertEqual(error_stringio.getvalue(),
+                    "Unrecognized unit. Please select usec, msec, or sec.\n")
+
     def test_main_exception(self):
         with captured_stderr() as error_stringio:
             s = self.run_main(switches=['1/0'])
diff --git a/Lib/timeit.py b/Lib/timeit.py
--- a/Lib/timeit.py
+++ b/Lib/timeit.py
@@ -19,6 +19,7 @@
   -t/--time: use time.time() (deprecated)
   -c/--clock: use time.clock() (deprecated)
   -v/--verbose: print raw timing results; repeat for more digits precision
+  -u/--unit: set the output time unit (usec, msec, or sec)
   -h/--help: print this usage message and exit
   --: separate options from statement, use when statement starts with -
   statement: statement to be timed (default 'pass')
@@ -250,10 +251,10 @@
         args = sys.argv[1:]
     import getopt
     try:
-        opts, args = getopt.getopt(args, "n:s:r:tcpvh",
+        opts, args = getopt.getopt(args, "n:u:s:r:tcpvh",
                                    ["number=", "setup=", "repeat=",
                                     "time", "clock", "process",
-                                    "verbose", "help"])
+                                    "verbose", "unit=", "help"])
     except getopt.error as err:
         print(err)
         print("use -h/--help for command line help")
@@ -264,12 +265,21 @@
     setup = []
     repeat = default_repeat
     verbose = 0
+    time_unit = None
+    units = {"usec": 1, "msec": 1e3, "sec": 1e6}
     precision = 3
     for o, a in opts:
         if o in ("-n", "--number"):
             number = int(a)
         if o in ("-s", "--setup"):
             setup.append(a)
+        if o in ("-u", "--unit"):
+            if a in units:
+                time_unit = a
+            else:
+                print("Unrecognized unit. Please select usec, msec, or sec.",
+                    file=sys.stderr)
+                return 2
         if o in ("-r", "--repeat"):
             repeat = int(a)
             if repeat <= 0:
@@ -319,15 +329,21 @@
         print("raw times:", " ".join(["%.*g" % (precision, x) for x in r]))
     print("%d loops," % number, end=' ')
     usec = best * 1e6 / number
-    if usec < 1000:
-        print("best of %d: %.*g usec per loop" % (repeat, precision, usec))
+    if time_unit is not None:
+        print("best of %d: %.*g %s per loop" % (repeat, precision,
+                                             usec/units[time_unit], time_unit))
     else:
-        msec = usec / 1000
-        if msec < 1000:
-            print("best of %d: %.*g msec per loop" % (repeat, precision, msec))
+        if usec < 1000:
+            print("best of %d: %.*g usec per loop" % (repeat, precision, usec))
         else:
-            sec = msec / 1000
-            print("best of %d: %.*g sec per loop" % (repeat, precision, sec))
+            msec = usec / 1000
+            if msec < 1000:
+                print("best of %d: %.*g msec per loop" % (repeat,
+                                                          precision, msec))
+            else:
+                sec = msec / 1000
+                print("best of %d: %.*g sec per loop" % (repeat,
+                                                         precision, sec))
     return None
 
 if __name__ == "__main__":
diff --git a/Misc/NEWS b/Misc/NEWS
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -18,6 +18,9 @@
 Library
 -------
 
+- Issue #18983: Allow selection of output units in timeit.
+  Patch by Serhiy Storchaka.
+
 - Issue #23631: Fix traceback.format_list when a traceback has been mutated.
 
 - Issue #23568: Add rdivmod support to MagicMock() objects.

-- 
Repository URL: https://hg.python.org/cpython


More information about the Python-checkins mailing list