##// END OF EJS Templates
Merge pull request #2855 from JanSchulz/2751_timit...
Thomas Kluyver -
r9483:50cb32f8 merge
parent child Browse files
Show More
@@ -1,3 +1,4 b''
1 # -*- coding: utf-8 -*-
1 """Implementation of execution-related magic functions.
2 """Implementation of execution-related magic functions.
2 """
3 """
3 #-----------------------------------------------------------------------------
4 #-----------------------------------------------------------------------------
@@ -675,7 +676,7 b' python-profiler package from non-free.""")'
675 del sys.modules[main_mod_name]
676 del sys.modules[main_mod_name]
676
677
677 return stats
678 return stats
678
679
679 @skip_doctest
680 @skip_doctest
680 @line_cell_magic
681 @line_cell_magic
681 def timeit(self, line='', cell=None):
682 def timeit(self, line='', cell=None):
@@ -746,31 +747,6 b' python-profiler package from non-free.""")'
746 those from %timeit."""
747 those from %timeit."""
747
748
748 import timeit
749 import timeit
749 import math
750
751 # XXX: Unfortunately the unicode 'micro' symbol can cause problems in
752 # certain terminals. Until we figure out a robust way of
753 # auto-detecting if the terminal can deal with it, use plain 'us' for
754 # microseconds. I am really NOT happy about disabling the proper
755 # 'micro' prefix, but crashing is worse... If anyone knows what the
756 # right solution for this is, I'm all ears...
757 #
758 # Note: using
759 #
760 # s = u'\xb5'
761 # s.encode(sys.getdefaultencoding())
762 #
763 # is not sufficient, as I've seen terminals where that fails but
764 # print s
765 #
766 # succeeds
767 #
768 # See bug: https://bugs.launchpad.net/ipython/+bug/348466
769
770 #units = [u"s", u"ms",u'\xb5',"ns"]
771 units = [u"s", u"ms",u'us',"ns"]
772
773 scaling = [1, 1e3, 1e6, 1e9]
774
750
775 opts, stmt = self.parse_options(line,'n:r:tcp:',
751 opts, stmt = self.parse_options(line,'n:r:tcp:',
776 posix=False, strict=False)
752 posix=False, strict=False)
@@ -855,50 +831,49 b' python-profiler package from non-free.""")'
855
831
856 best = min(timer.repeat(repeat, number)) / number
832 best = min(timer.repeat(repeat, number)) / number
857
833
858 if best > 0.0 and best < 1000.0:
834 print u"%d loops, best of %d: %s per loop" % (number, repeat,
859 order = min(-int(math.floor(math.log10(best)) // 3), 3)
835 _format_time(best, precision))
860 elif best >= 1000.0:
861 order = 0
862 else:
863 order = 3
864 print u"%d loops, best of %d: %.*g %s per loop" % (number, repeat,
865 precision,
866 best * scaling[order],
867 units[order])
868 if tc > tc_min:
836 if tc > tc_min:
869 print "Compiler time: %.2f s" % tc
837 print "Compiler time: %.2f s" % tc
870
838
871 @skip_doctest
839 @skip_doctest
872 @needs_local_scope
840 @needs_local_scope
873 @line_magic
841 @line_cell_magic
874 def time(self,parameter_s, local_ns=None):
842 def time(self,line='', cell=None, local_ns=None):
875 """Time execution of a Python statement or expression.
843 """Time execution of a Python statement or expression.
876
844
877 The CPU and wall clock times are printed, and the value of the
845 The CPU and wall clock times are printed, and the value of the
878 expression (if any) is returned. Note that under Win32, system time
846 expression (if any) is returned. Note that under Win32, system time
879 is always reported as 0, since it can not be measured.
847 is always reported as 0, since it can not be measured.
848
849 This function can be used both as a line and cell magic:
850
851 - In line mode you can time a single-line statement (though multiple
852 ones can be chained with using semicolons).
880
853
881 This function provides very basic timing functionality. In Python
854 - In cell mode, you can time the cell body (a directly
882 2.3, the timeit module offers more control and sophistication, so this
855 following statement raises an error).
883 could be rewritten to use it (patches welcome).
856
857 This function provides very basic timing functionality. Use the timeit
858 magic for more controll over the measurement.
884
859
885 Examples
860 Examples
886 --------
861 --------
887 ::
862 ::
888
863
889 In [1]: time 2**128
864 In [1]: %time 2**128
890 CPU times: user 0.00 s, sys: 0.00 s, total: 0.00 s
865 CPU times: user 0.00 s, sys: 0.00 s, total: 0.00 s
891 Wall time: 0.00
866 Wall time: 0.00
892 Out[1]: 340282366920938463463374607431768211456L
867 Out[1]: 340282366920938463463374607431768211456L
893
868
894 In [2]: n = 1000000
869 In [2]: n = 1000000
895
870
896 In [3]: time sum(range(n))
871 In [3]: %time sum(range(n))
897 CPU times: user 1.20 s, sys: 0.05 s, total: 1.25 s
872 CPU times: user 1.20 s, sys: 0.05 s, total: 1.25 s
898 Wall time: 1.37
873 Wall time: 1.37
899 Out[3]: 499999500000L
874 Out[3]: 499999500000L
900
875
901 In [4]: time print 'hello world'
876 In [4]: %time print 'hello world'
902 hello world
877 hello world
903 CPU times: user 0.00 s, sys: 0.00 s, total: 0.00 s
878 CPU times: user 0.00 s, sys: 0.00 s, total: 0.00 s
904 Wall time: 0.00
879 Wall time: 0.00
@@ -909,19 +884,25 b' python-profiler package from non-free.""")'
909 the expression can take a noticeable amount of time to compute, that
884 the expression can take a noticeable amount of time to compute, that
910 time is purely due to the compilation:
885 time is purely due to the compilation:
911
886
912 In [5]: time 3**9999;
887 In [5]: %time 3**9999;
913 CPU times: user 0.00 s, sys: 0.00 s, total: 0.00 s
888 CPU times: user 0.00 s, sys: 0.00 s, total: 0.00 s
914 Wall time: 0.00 s
889 Wall time: 0.00 s
915
890
916 In [6]: time 3**999999;
891 In [6]: %time 3**999999;
917 CPU times: user 0.00 s, sys: 0.00 s, total: 0.00 s
892 CPU times: user 0.00 s, sys: 0.00 s, total: 0.00 s
918 Wall time: 0.00 s
893 Wall time: 0.00 s
919 Compiler : 0.78 s
894 Compiler : 0.78 s
920 """
895 """
921
896
922 # fail immediately if the given expression can't be compiled
897 # fail immediately if the given expression can't be compiled
923
898
924 expr = self.shell.prefilter(parameter_s,False)
899 if line and cell:
900 raise UsageError("Can't use statement directly after '%%time'!")
901
902 if cell:
903 expr = self.shell.prefilter(cell,False)
904 else:
905 expr = self.shell.prefilter(line,False)
925
906
926 # Minimum time above which parse time will be reported
907 # Minimum time above which parse time will be reported
927 tp_min = 0.1
908 tp_min = 0.1
@@ -967,13 +948,13 b' python-profiler package from non-free.""")'
967 cpu_user = end[0]-st[0]
948 cpu_user = end[0]-st[0]
968 cpu_sys = end[1]-st[1]
949 cpu_sys = end[1]-st[1]
969 cpu_tot = cpu_user+cpu_sys
950 cpu_tot = cpu_user+cpu_sys
970 print "CPU times: user %.2f s, sys: %.2f s, total: %.2f s" % \
951 print "CPU times: user %s, sys: %s, total: %s" % \
971 (cpu_user,cpu_sys,cpu_tot)
952 (_format_time(cpu_user),_format_time(cpu_sys),_format_time(cpu_tot))
972 print "Wall time: %.2f s" % wall_time
953 print "Wall time: %s" % _format_time(wall_time)
973 if tc > tc_min:
954 if tc > tc_min:
974 print "Compiler : %.2f s" % tc
955 print "Compiler : %s" % _format_time(tc)
975 if tp > tp_min:
956 if tp > tp_min:
976 print "Parser : %.2f s" % tp
957 print "Parser : %s" % _format_time(tp)
977 return out
958 return out
978
959
979 @skip_doctest
960 @skip_doctest
@@ -1092,3 +1073,44 b' def parse_breakpoint(text, current_file):'
1092 return current_file, int(text)
1073 return current_file, int(text)
1093 else:
1074 else:
1094 return text[:colon], int(text[colon+1:])
1075 return text[:colon], int(text[colon+1:])
1076
1077 def _format_time(timespan, precision=3):
1078 """Formats the timespan in a human readable form"""
1079 import math
1080
1081 if timespan >= 60.0:
1082 # we have more than a minute, format that in a human readable form
1083 # Idea from http://snipplr.com/view/5713/
1084 parts = [("d", 60*60*24),("h", 60*60),("min", 60), ("s", 1)]
1085 time = []
1086 leftover = timespan
1087 for suffix, length in parts:
1088 value = int(leftover / length)
1089 if value > 0:
1090 leftover = leftover % length
1091 time.append(u'%s%s' % (str(value), suffix))
1092 if leftover < 1:
1093 break
1094 return " ".join(time)
1095
1096
1097 # Unfortunately the unicode 'micro' symbol can cause problems in
1098 # certain terminals.
1099 # See bug: https://bugs.launchpad.net/ipython/+bug/348466
1100 # Try to prevent crashes by being more secure than it needs to
1101 # E.g. eclipse is able to print a µ, but has no sys.stdout.encoding set.
1102 units = [u"s", u"ms",u'us',"ns"] # the save value
1103 if hasattr(sys.stdout, 'encoding') and sys.stdout.encoding:
1104 try:
1105 u'\xb5'.encode(sys.stdout.encoding)
1106 units = [u"s", u"ms",u'\xb5s',"ns"]
1107 except:
1108 pass
1109 scaling = [1, 1e3, 1e6, 1e9]
1110
1111 if timespan > 0.0:
1112 order = min(-int(math.floor(math.log10(timespan)) // 3), 3)
1113 else:
1114 order = 3
1115 ret = u"%.*g %s" % (precision, timespan * scaling[order], units[order])
1116 return ret
@@ -262,9 +262,6 b' def test_reset_in_length():'
262 _ip.run_cell("reset -f in")
262 _ip.run_cell("reset -f in")
263 nt.assert_true(len(_ip.user_ns['In']) == _ip.displayhook.prompt_count+1)
263 nt.assert_true(len(_ip.user_ns['In']) == _ip.displayhook.prompt_count+1)
264
264
265 def test_time():
266 _ip.magic('time None')
267
268 def test_tb_syntaxerror():
265 def test_tb_syntaxerror():
269 """test %tb after a SyntaxError"""
266 """test %tb after a SyntaxError"""
270 ip = get_ipython()
267 ip = get_ipython()
@@ -286,13 +283,13 b' def test_tb_syntaxerror():'
286 def test_time():
283 def test_time():
287 ip = get_ipython()
284 ip = get_ipython()
288
285
289 with tt.AssertPrints("CPU times: user 0.00 s, sys: 0.00 s, total: 0.00 s"):
286 with tt.AssertPrints("CPU times: user 0 ns, sys: 0 ns, total: 0 ns"):
290 ip.run_cell("%time None")
287 ip.run_cell("%time None")
291
288
292 ip.run_cell("def f(kmjy):\n"
289 ip.run_cell("def f(kmjy):\n"
293 " %time print (2*kmjy)")
290 " %time print (2*kmjy)")
294
291
295 with tt.AssertPrints("CPU times: user 0.00 s, sys: 0.00 s, total: 0.00 s"):
292 with tt.AssertPrints("CPU times: user 0 ns, sys: 0 ns, total: 0 ns"):
296 with tt.AssertPrints("hihi", suppress=False):
293 with tt.AssertPrints("hihi", suppress=False):
297 ip.run_cell("f('hi')")
294 ip.run_cell("f('hi')")
298
295
General Comments 0
You need to be logged in to leave comments. Login now