timer.py 1.8 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465
  1. import time
  2. class _Timer:
  3. """A running stat for conveniently logging the duration of a code block.
  4. Example:
  5. wait_timer = TimerStat()
  6. with wait_timer:
  7. ray.wait(...)
  8. Note that this class is *not* thread-safe.
  9. """
  10. def __init__(self, window_size=10):
  11. self._window_size = window_size
  12. self._samples = []
  13. self._units_processed = []
  14. self._start_time = None
  15. self._total_time = 0.0
  16. self.count = 0
  17. def __enter__(self):
  18. assert self._start_time is None, "concurrent updates not supported"
  19. self._start_time = time.time()
  20. def __exit__(self, exc_type, exc_value, tb):
  21. assert self._start_time is not None
  22. time_delta = time.time() - self._start_time
  23. self.push(time_delta)
  24. self._start_time = None
  25. def push(self, time_delta):
  26. self._samples.append(time_delta)
  27. if len(self._samples) > self._window_size:
  28. self._samples.pop(0)
  29. self.count += 1
  30. self._total_time += time_delta
  31. def push_units_processed(self, n):
  32. self._units_processed.append(n)
  33. if len(self._units_processed) > self._window_size:
  34. self._units_processed.pop(0)
  35. def has_units_processed(self):
  36. return len(self._units_processed) > 0
  37. @property
  38. def mean(self):
  39. if len(self._samples) == 0:
  40. return 0.0
  41. return float(sum(self._samples)) / len(self._samples)
  42. @property
  43. def mean_units_processed(self):
  44. if len(self._units_processed) == 0:
  45. return 0.0
  46. return float(sum(self._units_processed)) / len(self._units_processed)
  47. @property
  48. def mean_throughput(self):
  49. time_total = float(sum(self._samples))
  50. if not time_total:
  51. return 0.0
  52. return float(sum(self._units_processed)) / time_total