11import logging
22import threading
33import time
4- from typing import Optional
4+ from typing import Dict , Optional
55
66logger = logging .getLogger (__name__ )
77
88
99class Context :
1010 """
11- Class that holds the total execution time and call count of potentially multiple executions of the same label.
12- Reports its contents as a single-line string.
11+ Class that holds the start time of an execution block.
12+ Meant to be used in a "with" statement.
13+ Reports its results to the given profiler at the exit.
1314
14- TODO: Make profiles nestable by accumulating them at the context close .
15+ This class is not publically accessible .
1516 """
1617
17- def __init__ (self , label : str , profiler : Profiler ):
18+ def __init__ (self , label : str , profiler ):
1819 self .__profiler = profiler
1920
2021 self .__label = label
@@ -32,25 +33,24 @@ def __exit__(self, exc_type, exc_val, exc_tb):
3233
3334class Profile :
3435 """
35- Class that holds the total execution time and call count of potentially multiple executions of the same label.
36+ Class that holds the total execution time and call count
37+ of potentially multiple executions of the same label.
3638 Reports its contents as a single-line string.
37-
38- TODO: Make profiles nestable by accumulating them at the context close.
3939 """
4040
4141 def __init__ (self , label ):
4242 self .__label = label
43- self .__seconds = 0.0
44- self .__count = 0
43+ self .seconds = 0.0
44+ self .count = 0
4545
4646 def __str__ (self ):
47- if self .__count == 0 :
47+ if self .count == 0 :
4848 average = 0.0
4949 else :
50- average = self .__seconds / self .__count
50+ average = self .seconds / self .count
5151
5252 return (
53- f"{ self .__label } called { self .__count } times"
53+ f"{ self .__label } called { self .count } times"
5454 f" for average of { '%0.3f' % average } seconds"
5555 )
5656
@@ -62,38 +62,47 @@ class Profiler:
6262 """
6363
6464 def __init__ (self ):
65- self .__profiles = {}
65+ self .__profiles : Dict [ str , Profile ] = {}
6666 self .__lock = threading .RLock ()
6767
68- def profile (self , label : str ) -> Context :
68+ def context (self , label : str ) -> Context :
6969 """
70- Return a context to hold the profile timing.
70+ Return a context to hold the profile timing for a code block .
7171
7272 Args:
7373 label (str): label identifying the profile
7474
7575 Returns:
76- Profile : a new profile object, or previously existing one
76+ Context : a new context object
7777 """
7878 return Context (label , self )
7979
80- def accumulate (self , label : str , seconds : float ) -> None :
80+ def profile (self , label : str ) -> Profile :
8181 """
82- Accumulate a report into the profile for the given label.
82+ Make the accumulation profile for the given label.
8383 Uses previously existing profile, if any, or makes a new instance.
8484
8585 Args:
8686 label (str): label identifying the profile
87-
88- Returns:
89- Profile: a new profile object, or previously existing one
9087 """
9188 with self .__lock :
9289 profile = self .__profiles .get (label )
9390 if profile is None :
9491 profile = Profile (label )
9592 self .__profiles [label ] = profile
9693
94+ return profile
95+
96+ def accumulate (self , label : str , seconds : float ) -> None :
97+ """
98+ Accumulate a report into the profile for the given label.
99+ Uses previously existing profile, if any, or makes a new instance.
100+
101+ Args:
102+ label (str): label identifying the profile
103+ seconds (float): the number of seconds to accumulate
104+ """
105+ profile = self .profile (label )
97106 profile .seconds += seconds
98107 profile .count += 1
99108
0 commit comments