]> granicus.if.org Git - python/commitdiff
Issue #18983: Allow selection of output units in timeit.
authorRobert Collins <rbtcollins@hp.com>
Tue, 17 Mar 2015 20:54:50 +0000 (09:54 +1300)
committerRobert Collins <rbtcollins@hp.com>
Tue, 17 Mar 2015 20:54:50 +0000 (09:54 +1300)
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.

Doc/library/timeit.rst
Lib/test/test_timeit.py
Lib/timeit.py
Misc/NEWS

index 17588bdc87fe682c5a378bfa509be7703383e335..3ef9f3e396b96ba36e184ad96a191893e4e816ab 100644 (file)
@@ -179,7 +179,7 @@ Command-Line Interface
 
 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 @@ Where the following options are understood:
 
    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)
index 267d2c80c90a19af76a4cd5fbc0979862dfbcb5e..eebad185010639569442e2d1d19ea1a460861d33 100644 (file)
@@ -312,6 +312,26 @@ class TestTimeit(unittest.TestCase):
                 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'])
index 38077941fe89593a53a848b0a768da43f299abbd..caa7da3391e26497d2d4e249a181ab5a77baecc2 100755 (executable)
@@ -19,6 +19,7 @@ Options:
   -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 @@ def main(args=None, *, _wrap_timer=None):
         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 @@ def main(args=None, *, _wrap_timer=None):
     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 @@ def main(args=None, *, _wrap_timer=None):
         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__":
index d3d4d8f6126be82e6fc3e2e8b2fcda139907b172..dcc988f47dd3702e3410783855d006aadca6eb23 100644 (file)
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -18,6 +18,9 @@ Core and Builtins
 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.