1 # encoding: utf-8 2 """ 3 Utilities for timing code execution. 4 """ 5 6 #----------------------------------------------------------------------------- 7 # Copyright (C) 2008-2011 The IPython Development Team 8 # 9 # Distributed under the terms of the BSD License. The full license is in 10 # the file COPYING, distributed as part of this software. 11 #----------------------------------------------------------------------------- 12 13 #----------------------------------------------------------------------------- 14 # Imports 15 #----------------------------------------------------------------------------- 16 17 import time 18 19 #----------------------------------------------------------------------------- 20 # Code 21 #----------------------------------------------------------------------------- 22 23 # If possible (Unix), use the resource module instead of time.clock() 24 try: 25 import resource 26 except ModuleNotFoundError: 27 resource = None # type: ignore [assignment] 28 29 # Some implementations (like jyputerlite) don't have getrusage 30 if resource is not None and hasattr(resource, "getrusage"): 31 def clocku(): 32 """clocku() -> floating point number 33 34 Return the *USER* CPU time in seconds since the start of the process. 35 This is done via a call to resource.getrusage, so it avoids the 36 wraparound problems in time.clock().""" 37 38 return resource.getrusage(resource.RUSAGE_SELF)[0] 39 40 def clocks(): 41 """clocks() -> floating point number 42 43 Return the *SYSTEM* CPU time in seconds since the start of the process. 44 This is done via a call to resource.getrusage, so it avoids the 45 wraparound problems in time.clock().""" 46 47 return resource.getrusage(resource.RUSAGE_SELF)[1] 48 49 def clock(): 50 """clock() -> floating point number 51 52 Return the *TOTAL USER+SYSTEM* CPU time in seconds since the start of 53 the process. This is done via a call to resource.getrusage, so it 54 avoids the wraparound problems in time.clock().""" 55 56 u,s = resource.getrusage(resource.RUSAGE_SELF)[:2] 57 return u+s 58 59 def clock2(): 60 """clock2() -> (t_user,t_system) 61 62 Similar to clock(), but return a tuple of user/system times.""" 63 return resource.getrusage(resource.RUSAGE_SELF)[:2] 64 65 else: 66 # There is no distinction of user/system time under windows, so we just use 67 # time.process_time() for everything... 68 clocku = clocks = clock = time.process_time 69 70 def clock2(): 71 """Under windows, system CPU time can't be measured. 72 73 This just returns process_time() and zero.""" 74 return time.process_time(), 0.0 75 76 77 def timings_out(reps,func,*args,**kw): 78 """timings_out(reps,func,*args,**kw) -> (t_total,t_per_call,output) 79 80 Execute a function reps times, return a tuple with the elapsed total 81 CPU time in seconds, the time per call and the function's output. 82 83 Under Unix, the return value is the sum of user+system time consumed by 84 the process, computed via the resource module. This prevents problems 85 related to the wraparound effect which the time.clock() function has. 86 87 Under Windows the return value is in wall clock seconds. See the 88 documentation for the time module for more details.""" 89 90 reps = int(reps) 91 assert reps >=1, 'reps must be >= 1' 92 if reps==1: 93 start = clock() 94 out = func(*args,**kw) 95 tot_time = clock()-start 96 else: 97 rng = range(reps-1) # the last time is executed separately to store output 98 start = clock() 99 for dummy in rng: func(*args,**kw) 100 out = func(*args,**kw) # one last time 101 tot_time = clock()-start 102 av_time = tot_time / reps 103 return tot_time,av_time,out 104 105 106 def timings(reps,func,*args,**kw): 107 """timings(reps,func,*args,**kw) -> (t_total,t_per_call) 108 109 Execute a function reps times, return a tuple with the elapsed total CPU 110 time in seconds and the time per call. These are just the first two values 111 in timings_out().""" 112 113 return timings_out(reps,func,*args,**kw)[0:2] 114 115 116 def timing(func,*args,**kw): 117 """timing(func,*args,**kw) -> t_total 118 119 Execute a function once, return the elapsed total CPU time in 120 seconds. This is just the first value in timings_out().""" 121 122 return timings_out(1,func,*args,**kw)[0] 123 124