##// 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 2 """Implementation of execution-related magic functions.
2 3 """
3 4 #-----------------------------------------------------------------------------
@@ -675,7 +676,7 b' python-profiler package from non-free.""")'
675 676 del sys.modules[main_mod_name]
676 677
677 678 return stats
678
679
679 680 @skip_doctest
680 681 @line_cell_magic
681 682 def timeit(self, line='', cell=None):
@@ -746,31 +747,6 b' python-profiler package from non-free.""")'
746 747 those from %timeit."""
747 748
748 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 751 opts, stmt = self.parse_options(line,'n:r:tcp:',
776 752 posix=False, strict=False)
@@ -855,50 +831,49 b' python-profiler package from non-free.""")'
855 831
856 832 best = min(timer.repeat(repeat, number)) / number
857 833
858 if best > 0.0 and best < 1000.0:
859 order = min(-int(math.floor(math.log10(best)) // 3), 3)
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])
834 print u"%d loops, best of %d: %s per loop" % (number, repeat,
835 _format_time(best, precision))
868 836 if tc > tc_min:
869 837 print "Compiler time: %.2f s" % tc
870 838
871 839 @skip_doctest
872 840 @needs_local_scope
873 @line_magic
874 def time(self,parameter_s, local_ns=None):
841 @line_cell_magic
842 def time(self,line='', cell=None, local_ns=None):
875 843 """Time execution of a Python statement or expression.
876 844
877 845 The CPU and wall clock times are printed, and the value of the
878 846 expression (if any) is returned. Note that under Win32, system time
879 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
882 2.3, the timeit module offers more control and sophistication, so this
883 could be rewritten to use it (patches welcome).
854 - In cell mode, you can time the cell body (a directly
855 following statement raises an error).
856
857 This function provides very basic timing functionality. Use the timeit
858 magic for more controll over the measurement.
884 859
885 860 Examples
886 861 --------
887 862 ::
888 863
889 In [1]: time 2**128
864 In [1]: %time 2**128
890 865 CPU times: user 0.00 s, sys: 0.00 s, total: 0.00 s
891 866 Wall time: 0.00
892 867 Out[1]: 340282366920938463463374607431768211456L
893 868
894 869 In [2]: n = 1000000
895 870
896 In [3]: time sum(range(n))
871 In [3]: %time sum(range(n))
897 872 CPU times: user 1.20 s, sys: 0.05 s, total: 1.25 s
898 873 Wall time: 1.37
899 874 Out[3]: 499999500000L
900 875
901 In [4]: time print 'hello world'
876 In [4]: %time print 'hello world'
902 877 hello world
903 878 CPU times: user 0.00 s, sys: 0.00 s, total: 0.00 s
904 879 Wall time: 0.00
@@ -909,19 +884,25 b' python-profiler package from non-free.""")'
909 884 the expression can take a noticeable amount of time to compute, that
910 885 time is purely due to the compilation:
911 886
912 In [5]: time 3**9999;
887 In [5]: %time 3**9999;
913 888 CPU times: user 0.00 s, sys: 0.00 s, total: 0.00 s
914 889 Wall time: 0.00 s
915 890
916 In [6]: time 3**999999;
891 In [6]: %time 3**999999;
917 892 CPU times: user 0.00 s, sys: 0.00 s, total: 0.00 s
918 893 Wall time: 0.00 s
919 894 Compiler : 0.78 s
920 895 """
921 896
922 897 # fail immediately if the given expression can't be compiled
923
924 expr = self.shell.prefilter(parameter_s,False)
898
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 907 # Minimum time above which parse time will be reported
927 908 tp_min = 0.1
@@ -967,13 +948,13 b' python-profiler package from non-free.""")'
967 948 cpu_user = end[0]-st[0]
968 949 cpu_sys = end[1]-st[1]
969 950 cpu_tot = cpu_user+cpu_sys
970 print "CPU times: user %.2f s, sys: %.2f s, total: %.2f s" % \
971 (cpu_user,cpu_sys,cpu_tot)
972 print "Wall time: %.2f s" % wall_time
951 print "CPU times: user %s, sys: %s, total: %s" % \
952 (_format_time(cpu_user),_format_time(cpu_sys),_format_time(cpu_tot))
953 print "Wall time: %s" % _format_time(wall_time)
973 954 if tc > tc_min:
974 print "Compiler : %.2f s" % tc
955 print "Compiler : %s" % _format_time(tc)
975 956 if tp > tp_min:
976 print "Parser : %.2f s" % tp
957 print "Parser : %s" % _format_time(tp)
977 958 return out
978 959
979 960 @skip_doctest
@@ -1092,3 +1073,44 b' def parse_breakpoint(text, current_file):'
1092 1073 return current_file, int(text)
1093 1074 else:
1094 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 262 _ip.run_cell("reset -f in")
263 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 265 def test_tb_syntaxerror():
269 266 """test %tb after a SyntaxError"""
270 267 ip = get_ipython()
@@ -286,13 +283,13 b' def test_tb_syntaxerror():'
286 283 def test_time():
287 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 287 ip.run_cell("%time None")
291 288
292 289 ip.run_cell("def f(kmjy):\n"
293 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 293 with tt.AssertPrints("hihi", suppress=False):
297 294 ip.run_cell("f('hi')")
298 295
General Comments 0
You need to be logged in to leave comments. Login now