timing.py 4.2 KB

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