bluer-options 5.166.1__py3-none-any.whl → 5.170.1__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of bluer-options might be problematic. Click here for more details.
- bluer_options/__init__.py +1 -1
- bluer_options/string/functions.py +1 -1
- bluer_options/timing/__init__.py +4 -0
- bluer_options/timing/classes.py +117 -0
- bluer_options/timing/elapsed_timer.py +42 -0
- {bluer_options-5.166.1.dist-info → bluer_options-5.170.1.dist-info}/METADATA +1 -1
- {bluer_options-5.166.1.dist-info → bluer_options-5.170.1.dist-info}/RECORD +10 -8
- bluer_options/elapsed_timer.py +0 -23
- {bluer_options-5.166.1.dist-info → bluer_options-5.170.1.dist-info}/WHEEL +0 -0
- {bluer_options-5.166.1.dist-info → bluer_options-5.170.1.dist-info}/licenses/LICENSE +0 -0
- {bluer_options-5.166.1.dist-info → bluer_options-5.170.1.dist-info}/top_level.txt +0 -0
bluer_options/__init__.py
CHANGED
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
import time
|
|
2
|
+
from typing import List
|
|
3
|
+
from collections import defaultdict
|
|
4
|
+
from functools import wraps
|
|
5
|
+
|
|
6
|
+
from bluer_options import string
|
|
7
|
+
from bluer_options.logger import logger
|
|
8
|
+
from bluer_options.logger.config import log_list
|
|
9
|
+
from bluer_options.timing.elapsed_timer import ElapsedTimer
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
class Timing:
|
|
13
|
+
def __init__(self):
|
|
14
|
+
self._active = {}
|
|
15
|
+
self.stats = defaultdict(lambda: {"count": 0, "total": 0.0})
|
|
16
|
+
self.elapsed_timer = ElapsedTimer()
|
|
17
|
+
|
|
18
|
+
def start(self, keyword: str):
|
|
19
|
+
"""Start timing a code block identified by 'keyword'."""
|
|
20
|
+
self._active[keyword] = time.perf_counter()
|
|
21
|
+
|
|
22
|
+
def stop(self, keyword: str):
|
|
23
|
+
"""Stop timing for 'keyword' and record elapsed time."""
|
|
24
|
+
if keyword not in self._active:
|
|
25
|
+
raise RuntimeError(f"No active timer for {keyword}")
|
|
26
|
+
|
|
27
|
+
elapsed = time.perf_counter() - self._active.pop(keyword)
|
|
28
|
+
self.stats[keyword]["count"] += 1
|
|
29
|
+
self.stats[keyword]["total"] += elapsed
|
|
30
|
+
|
|
31
|
+
return elapsed
|
|
32
|
+
|
|
33
|
+
def as_list(self, **kwgrs) -> List[str]:
|
|
34
|
+
lines = []
|
|
35
|
+
# sort items by total time (descending)
|
|
36
|
+
for k, v in sorted(
|
|
37
|
+
self.stats.items(),
|
|
38
|
+
key=lambda item: item[1]["total"],
|
|
39
|
+
reverse=True,
|
|
40
|
+
):
|
|
41
|
+
avg = v["total"] / v["count"]
|
|
42
|
+
lines.append(
|
|
43
|
+
"{}: called {:,} time(s), total {}, avg {}".format(
|
|
44
|
+
k,
|
|
45
|
+
v["count"],
|
|
46
|
+
string.pretty_duration(v["total"], **kwgrs),
|
|
47
|
+
string.pretty_duration(avg, **kwgrs),
|
|
48
|
+
)
|
|
49
|
+
)
|
|
50
|
+
return lines
|
|
51
|
+
|
|
52
|
+
def log(
|
|
53
|
+
self,
|
|
54
|
+
include_ms: bool = True,
|
|
55
|
+
largest: bool = True,
|
|
56
|
+
short: bool = True,
|
|
57
|
+
**kwargs,
|
|
58
|
+
):
|
|
59
|
+
log_list(
|
|
60
|
+
logger,
|
|
61
|
+
"took {} for".format(
|
|
62
|
+
self.elapsed_timer.as_str(
|
|
63
|
+
stop=False,
|
|
64
|
+
include_ms=include_ms,
|
|
65
|
+
largest=largest,
|
|
66
|
+
short=short,
|
|
67
|
+
)
|
|
68
|
+
),
|
|
69
|
+
self.as_list(
|
|
70
|
+
include_ms=include_ms,
|
|
71
|
+
largest=largest,
|
|
72
|
+
short=short,
|
|
73
|
+
),
|
|
74
|
+
"function call(s):",
|
|
75
|
+
**kwargs,
|
|
76
|
+
)
|
|
77
|
+
|
|
78
|
+
def reset(self):
|
|
79
|
+
self._active = {}
|
|
80
|
+
self.stats = defaultdict(lambda: {"count": 0, "total": 0.0})
|
|
81
|
+
self.elapsed_timer.reset()
|
|
82
|
+
|
|
83
|
+
def time(self, arg=None):
|
|
84
|
+
"""Use as @timing.time, @timing.time(), or @timing.time('custom')"""
|
|
85
|
+
|
|
86
|
+
# Case 1: @timing.time (no parentheses, arg is the function)
|
|
87
|
+
if callable(arg):
|
|
88
|
+
func = arg
|
|
89
|
+
name = func.__name__
|
|
90
|
+
|
|
91
|
+
@wraps(func)
|
|
92
|
+
def inner(*args, **kwargs):
|
|
93
|
+
self.start(name)
|
|
94
|
+
try:
|
|
95
|
+
return func(*args, **kwargs)
|
|
96
|
+
finally:
|
|
97
|
+
self.stop(name)
|
|
98
|
+
|
|
99
|
+
return inner
|
|
100
|
+
|
|
101
|
+
# Case 2: @timing.time() or @timing.time("custom")
|
|
102
|
+
keyword = arg # may be None or str
|
|
103
|
+
|
|
104
|
+
def decorator(func):
|
|
105
|
+
name = keyword or func.__name__
|
|
106
|
+
|
|
107
|
+
@wraps(func)
|
|
108
|
+
def inner(*args, **kwargs):
|
|
109
|
+
self.start(name)
|
|
110
|
+
try:
|
|
111
|
+
return func(*args, **kwargs)
|
|
112
|
+
finally:
|
|
113
|
+
self.stop(name)
|
|
114
|
+
|
|
115
|
+
return inner
|
|
116
|
+
|
|
117
|
+
return decorator
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import time
|
|
2
|
+
from bluer_options import string
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
class ElapsedTimer:
|
|
6
|
+
def __init__(self):
|
|
7
|
+
self.start_time = time.time()
|
|
8
|
+
self.elapsed_time_ = None
|
|
9
|
+
|
|
10
|
+
def as_str(
|
|
11
|
+
self,
|
|
12
|
+
stop: bool = True,
|
|
13
|
+
**kwargs,
|
|
14
|
+
):
|
|
15
|
+
if stop:
|
|
16
|
+
self.stop()
|
|
17
|
+
|
|
18
|
+
elapsed_time = self.elapsed_time
|
|
19
|
+
|
|
20
|
+
return (
|
|
21
|
+
"None"
|
|
22
|
+
if elapsed_time is None
|
|
23
|
+
else string.pretty_duration(elapsed_time, **kwargs)
|
|
24
|
+
)
|
|
25
|
+
|
|
26
|
+
@property
|
|
27
|
+
def elapsed_time(self) -> float:
|
|
28
|
+
if self.start_time is None:
|
|
29
|
+
return self.elapsed_time_
|
|
30
|
+
|
|
31
|
+
return time.time() - self.start_time
|
|
32
|
+
|
|
33
|
+
def reset(self):
|
|
34
|
+
self.start_time = time.time()
|
|
35
|
+
self.elapsed_time_ = None
|
|
36
|
+
|
|
37
|
+
def stop(self):
|
|
38
|
+
if self.start_time is None:
|
|
39
|
+
return
|
|
40
|
+
|
|
41
|
+
self.elapsed_time_ = self.elapsed_time
|
|
42
|
+
self.start_time = None
|
|
@@ -1,7 +1,6 @@
|
|
|
1
|
-
bluer_options/__init__.py,sha256=
|
|
1
|
+
bluer_options/__init__.py,sha256=xmQ2FD7BLue2yqg6RBw4e6QSn6ZdB5rH-kDElX0T2qI,288
|
|
2
2
|
bluer_options/__main__.py,sha256=-6ce9W1uXkle4YtEYlSUMWxSmsur3dRDA4_MvNNhEVg,236
|
|
3
3
|
bluer_options/config.env,sha256=2AG3xuWiMqaNmlCNDWQOJ_AssKk7KXhn0XDIkHWNQ2Q,30
|
|
4
|
-
bluer_options/elapsed_timer.py,sha256=46e-g-bjC7J4hGOGKD12R90ficXzFYn84xlLX6l34I8,545
|
|
5
4
|
bluer_options/timer.py,sha256=UPmsfCjbEWpcjXgMpYemXieheMJH_UpuemhVGsKYVoE,2470
|
|
6
5
|
bluer_options/urls.py,sha256=paHaYlLMQOI46-EYNch5ohu9Q09BMkF2vvJy1QufrVI,19
|
|
7
6
|
bluer_options/.bash/alias.sh,sha256=8-t6sTIy3YjyMkFLArRc45U1lNBWWmG0dIhYuN3-wRo,890
|
|
@@ -59,12 +58,15 @@ bluer_options/options/classes.py,sha256=dcfGd34y6vDYvj-v-Bb5uOyy79mwV0s98czYFJ9h
|
|
|
59
58
|
bluer_options/string/__init__.py,sha256=MsbbLbg13Pmq2qkYqwOU1bc27_VvfiZ_alcKYH7zzI8,546
|
|
60
59
|
bluer_options/string/__main__.py,sha256=g8dVfG5eMRXJsyc2jv631qvRb40TsEq2OVhf6Dkluvw,1286
|
|
61
60
|
bluer_options/string/constants.py,sha256=hfUx6xihcOsTayceAumyxyV2fbAr45_o4J-4ejKWrgM,216
|
|
62
|
-
bluer_options/string/functions.py,sha256=
|
|
61
|
+
bluer_options/string/functions.py,sha256=ogHO3Yee365CE_LIM2gwdQYQKFzPJ5z-rDTdoOIOOUg,7939
|
|
63
62
|
bluer_options/terminal/__init__.py,sha256=kyNhbC5NVCuqrUhbbTeAOTW1ZO7MRRbi0RtXGBFKtJc,73
|
|
64
63
|
bluer_options/terminal/__main__.py,sha256=3o465bp44c2f1KHDn4j664hpbvu8wKOwQ2c1OPoa6Xc,902
|
|
65
64
|
bluer_options/terminal/functions.py,sha256=A23uHLeU4JIctmecOFk_KhIfOeHu-WMjnSzBj2KiF3U,1947
|
|
66
|
-
bluer_options
|
|
67
|
-
bluer_options
|
|
68
|
-
bluer_options
|
|
69
|
-
bluer_options-5.
|
|
70
|
-
bluer_options-5.
|
|
65
|
+
bluer_options/timing/__init__.py,sha256=CCIJKvRVdimLdk46WOc_C-t8HHTVFPdGxQTFCFrN5zc,127
|
|
66
|
+
bluer_options/timing/classes.py,sha256=iIzoMtR8SXNJcDGDPCJodRqUHPAPrEMTUCsMQ-BOuZg,3398
|
|
67
|
+
bluer_options/timing/elapsed_timer.py,sha256=ecM11nzXnoDL_k6p41YPH28-OLnYreg_CgPQlbv4mjI,897
|
|
68
|
+
bluer_options-5.170.1.dist-info/licenses/LICENSE,sha256=ogEPNDSH0_dhiv_lT3ifVIdgIzHAqNA_SemnxUfPBJk,7048
|
|
69
|
+
bluer_options-5.170.1.dist-info/METADATA,sha256=SHaZLZAKqmxmhIVAY0MzQAaPrXnyCr8Lbh3WOB_qePo,4951
|
|
70
|
+
bluer_options-5.170.1.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
|
71
|
+
bluer_options-5.170.1.dist-info/top_level.txt,sha256=yw9slt8n3R7IiYmf83OtHtB8Z-EgP9UwyQTk1EGiAJU,14
|
|
72
|
+
bluer_options-5.170.1.dist-info/RECORD,,
|
bluer_options/elapsed_timer.py
DELETED
|
@@ -1,23 +0,0 @@
|
|
|
1
|
-
import time
|
|
2
|
-
from bluer_options import string
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
class ElapsedTimer:
|
|
6
|
-
def __init__(self):
|
|
7
|
-
self.start_time = time.time()
|
|
8
|
-
self.elapsed_time = None
|
|
9
|
-
|
|
10
|
-
def stop(self):
|
|
11
|
-
if self.start_time is None:
|
|
12
|
-
return
|
|
13
|
-
|
|
14
|
-
self.elapsed_time = time.time() - self.start_time
|
|
15
|
-
self.start_time = None
|
|
16
|
-
|
|
17
|
-
def elapsed_pretty(self, **kwargs):
|
|
18
|
-
self.stop()
|
|
19
|
-
return (
|
|
20
|
-
"None"
|
|
21
|
-
if self.elapsed_time is None
|
|
22
|
-
else string.pretty_duration(self.elapsed_time, **kwargs)
|
|
23
|
-
)
|
|
File without changes
|
|
File without changes
|
|
File without changes
|