Coverage for python/lsst/dax/apdb/timer.py: 22%

58 statements  

« prev     ^ index     » next       coverage.py v7.4.4, created at 2024-04-13 09:59 +0000

1# This file is part of dax_apdb. 

2# 

3# Developed for the LSST Data Management System. 

4# This product includes software developed by the LSST Project 

5# (http://www.lsst.org). 

6# See the COPYRIGHT file at the top-level directory of this distribution 

7# for details of code ownership. 

8# 

9# This program is free software: you can redistribute it and/or modify 

10# it under the terms of the GNU General Public License as published by 

11# the Free Software Foundation, either version 3 of the License, or 

12# (at your option) any later version. 

13# 

14# This program is distributed in the hope that it will be useful, 

15# but WITHOUT ANY WARRANTY; without even the implied warranty of 

16# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 

17# GNU General Public License for more details. 

18# 

19# You should have received a copy of the GNU General Public License 

20# along with this program. If not, see <http://www.gnu.org/licenses/>. 

21 

22"""Module with methods to return timing information. 

23 

24This was developed as a part of a prototype for performance studies. It 

25could probably be removed in the production system. 

26""" 

27 

28from __future__ import annotations 

29 

30import logging 

31import resource 

32import time 

33from typing import Any 

34 

35_LOG = logging.getLogger(__name__) 

36 

37 

38class Timer: 

39 """ 

40 Instance of this class can be used to track consumed time. 

41 

42 This class is also a context manager and can be used in 

43 a `with` statement. By default it prints consumed CPU time 

44 and real time spent in a context. 

45 

46 Example: 

47 

48 with Timer('SelectTimer'): 

49 engine.execute('SELECT ...') 

50 

51 """ 

52 

53 def __init__(self, name: str = "", doPrint: bool = True): 

54 """ 

55 Parameters 

56 ---------- 

57 name : `str` 

58 Timer name, will be printed together with statistics. 

59 doPrint : `bool` 

60 If True then print statistics on exist from context. 

61 """ 

62 self._name = name 

63 self._print = doPrint 

64 

65 self._startReal = -1.0 

66 self._startUser = -1.0 

67 self._startSys = -1.0 

68 self._sumReal = 0.0 

69 self._sumUser = 0.0 

70 self._sumSys = 0.0 

71 

72 def start(self) -> Timer: 

73 """ 

74 Start timer. 

75 """ 

76 self._startReal = time.time() 

77 ru = resource.getrusage(resource.RUSAGE_SELF) 

78 self._startUser = ru.ru_utime 

79 self._startSys = ru.ru_stime 

80 return self 

81 

82 def stop(self) -> Timer: 

83 """ 

84 Stop timer. 

85 """ 

86 if self._startReal > 0: 

87 self._sumReal += time.time() - self._startReal 

88 ru = resource.getrusage(resource.RUSAGE_SELF) 

89 self._sumUser += ru.ru_utime - self._startUser 

90 self._sumSys += ru.ru_stime - self._startSys 

91 self._startReal = -1.0 

92 self._startUser = -1.0 

93 self._startSys = -1.0 

94 return self 

95 

96 def dump(self) -> Timer: 

97 """ 

98 Dump timer statistics 

99 """ 

100 _LOG.info("%s", self) 

101 return self 

102 

103 def __str__(self) -> str: 

104 real = self._sumReal 

105 user = self._sumUser 

106 sys = self._sumSys 

107 if self._startReal > 0: 

108 real += time.time() - self._startReal 

109 ru = resource.getrusage(resource.RUSAGE_SELF) 

110 user += ru.ru_utime - self._startUser 

111 sys += ru.ru_stime - self._startSys 

112 info = "real=%.3f user=%.3f sys=%.3f" % (real, user, sys) 

113 if self._name: 

114 info = self._name + ": " + info 

115 return info 

116 

117 def __enter__(self) -> Timer: 

118 """ 

119 Enter context, start timer 

120 """ 

121 self.start() 

122 return self 

123 

124 def __exit__(self, exc_type: type | None, exc_val: Any, exc_tb: Any) -> Any: 

125 """ 

126 Exit context, stop and dump timer 

127 """ 

128 if exc_type is None: 

129 self.stop() 

130 if self._print: 

131 self.dump() 

132 return False