##// END OF EJS Templates
Added mean + stdv to the %timeit magic - New tests pending - Corrected old ones
Pablo Galindo -
Show More
@@ -15,6 +15,7 b' import os'
15 15 import sys
16 16 import time
17 17 import timeit
18 import math
18 19 from pdb import Restart
19 20
20 21 # cProfile was added in Python2.5
@@ -71,22 +72,26 b' class TimeitResult(object):'
71 72
72 73 """
73 74
74 def __init__(self, loops, repeat, best, worst, all_runs, compile_time, precision):
75 def __init__(self, loops, repeat, average, stdev, all_runs, compile_time, precision):
75 76 self.loops = loops
76 77 self.repeat = repeat
77 self.best = best
78 self.worst = worst
78 self.average = average
79 self.stdev = stdev
79 80 self.all_runs = all_runs
80 81 self.compile_time = compile_time
81 82 self._precision = precision
82 83
83 84 def _repr_pretty_(self, p , cycle):
84 85 if self.loops == 1: # No s at "loops" if only one loop
85 unic = u"%d loop, best of %d: %s per loop" % (self.loops, self.repeat,
86 _format_time(self.best, self._precision))
86 unic = (u"%s loop, average of %d: %s +- %s per loop (using standard deviation)"
87 % (self.loops, self.repeat,
88 _format_time(self.average, self._precision),
89 _format_time(self.stdev, self._precision)))
87 90 else:
88 unic = u"%d loops, best of %d: %s per loop" % (self.loops, self.repeat,
89 _format_time(self.best, self._precision))
91 unic = (u"%s loops, average of %d: %s +- %s per loop (using standard deviation)"
92 % (self.loops, self.repeat,
93 _format_time(self.average, self._precision),
94 _format_time(self.stdev, self._precision)))
90 95 p.text(u'<TimeitResult : '+unic+u'>')
91 96
92 97
@@ -950,20 +955,20 b' python-profiler package from non-free.""")'
950 955 ::
951 956
952 957 In [1]: %timeit pass
953 10000000 loops, best of 3: 53.3 ns per loop
958 100000000 loops, average of 7: 5.48 ns +- 0.354 ns per loop (using standard deviation)
954 959
955 960 In [2]: u = None
956 961
957 962 In [3]: %timeit u is None
958 10000000 loops, best of 3: 184 ns per loop
963 10000000 loops, average of 7: 22.7 ns +- 2.33 ns per loop (using standard deviation)
959 964
960 965 In [4]: %timeit -r 4 u == None
961 1000000 loops, best of 4: 242 ns per loop
966 10000000 loops, average of 4: 27.5 ns +- 2.91 ns per loop (using standard deviation)
962 967
963 968 In [5]: import time
964 969
965 970 In [6]: %timeit -n1 time.sleep(2)
966 1 loop, best of 3: 2 s per loop
971 1 loop, average of 7: 2 s +- 4.71 µs per loop (using standard deviation)
967 972
968 973
969 974 The times reported by %timeit will be slightly higher than those
@@ -981,7 +986,8 b' python-profiler package from non-free.""")'
981 986
982 987 timefunc = timeit.default_timer
983 988 number = int(getattr(opts, "n", 0))
984 repeat = int(getattr(opts, "r", timeit.default_repeat))
989 default_repeat = 7 if timeit.default_repeat < 7 else timeit.default_repeat
990 repeat = int(getattr(opts, "r", default_repeat))
985 991 precision = int(getattr(opts, "p", 3))
986 992 quiet = 'q' in opts
987 993 return_result = 'o' in opts
@@ -1036,22 +1042,26 b' python-profiler package from non-free.""")'
1036 1042 # This is used to check if there is a huge difference between the
1037 1043 # best and worst timings.
1038 1044 # Issue: https://github.com/ipython/ipython/issues/6471
1039 worst_tuning = 0
1040 1045 if number == 0:
1041 1046 # determine number so that 0.2 <= total time < 2.0
1042 number = 1
1043 for _ in range(1, 10):
1047 for index in range(0, 10):
1048 number = 10 ** index
1044 1049 time_number = timer.timeit(number)
1045 worst_tuning = max(worst_tuning, time_number / number)
1046 1050 if time_number >= 0.2:
1047 1051 break
1048 number *= 10
1052
1049 1053 all_runs = timer.repeat(repeat, number)
1050 best = min(all_runs) / number
1054 timings = [ dt / number for dt in all_runs]
1055
1056 def _avg(numbers):
1057 return math.fsum(numbers) / len(numbers)
1058
1059 def _stdev(numbers):
1060 mean = _avg(numbers)
1061 return (math.fsum([(x - mean) ** 2 for x in numbers]) / len(numbers)) ** 0.5
1051 1062
1052 worst = max(all_runs) / number
1053 if worst_tuning:
1054 worst = max(worst, worst_tuning)
1063 average = _avg(timings)
1064 stdev = _stdev(timings)
1055 1065
1056 1066 if not quiet :
1057 1067 # Check best timing is greater than zero to avoid a
@@ -1059,20 +1069,20 b' python-profiler package from non-free.""")'
1059 1069 # In cases where the slowest timing is lesser than a micosecond
1060 1070 # we assume that it does not really matter if the fastest
1061 1071 # timing is 4 times faster than the slowest timing or not.
1062 if worst > 4 * best and best > 0 and worst > 1e-6:
1063 print("The slowest run took %0.2f times longer than the "
1064 "fastest. This could mean that an intermediate result "
1065 "is being cached." % (worst / best))
1066 1072 if number == 1: # No s at "loops" if only one loop
1067 print(u"%d loop, best of %d: %s per loop" % (number, repeat,
1068 _format_time(best, precision)))
1073 print(u"%s loop, average of %d: %s +- %s per loop (using standard deviation)"
1074 % (number, repeat,
1075 _format_time(average, precision),
1076 _format_time(stdev, precision)))
1069 1077 else:
1070 print(u"%d loops, best of %d: %s per loop" % (number, repeat,
1071 _format_time(best, precision)))
1078 print(u"%s loops, average of %d: %s +- %s per loop (using standard deviation)"
1079 % (number, repeat,
1080 _format_time(average, precision),
1081 _format_time(stdev, precision)))
1072 1082 if tc > tc_min:
1073 1083 print("Compiler time: %.2f s" % tc)
1074 1084 if return_result:
1075 return TimeitResult(number, repeat, best, worst, all_runs, tc, precision)
1085 return TimeitResult(number, repeat, average, stdev, all_runs, tc, precision)
1076 1086
1077 1087 @skip_doctest
1078 1088 @needs_local_scope
@@ -649,12 +649,12 b' class TestAstTransform(unittest.TestCase):'
649 649 called.add(x)
650 650 ip.push({'f':f})
651 651
652 with tt.AssertPrints("best of "):
652 with tt.AssertPrints("average of "):
653 653 ip.run_line_magic("timeit", "-n1 f(1)")
654 654 self.assertEqual(called, {-1})
655 655 called.clear()
656 656
657 with tt.AssertPrints("best of "):
657 with tt.AssertPrints("average of "):
658 658 ip.run_cell_magic("timeit", "-n1 f(2)", "f(3)")
659 659 self.assertEqual(called, {-2, -3})
660 660
@@ -722,12 +722,12 b' class TestAstTransform2(unittest.TestCase):'
722 722 called.add(x)
723 723 ip.push({'f':f})
724 724
725 with tt.AssertPrints("best of "):
725 with tt.AssertPrints("average of "):
726 726 ip.run_line_magic("timeit", "-n1 f(1)")
727 727 self.assertEqual(called, {(1,)})
728 728 called.clear()
729 729
730 with tt.AssertPrints("best of "):
730 with tt.AssertPrints("average of "):
731 731 ip.run_cell_magic("timeit", "-n1 f(2)", "f(3)")
732 732 self.assertEqual(called, {(2,), (3,)})
733 733
General Comments 0
You need to be logged in to leave comments. Login now