cengal.time_management.repeat_for_a_time.versions.v_0.repeat_for_a_time__python
1#!/usr/bin/env python 2# coding=utf-8 3 4# Copyright © 2012-2024 ButenkoMS. All rights reserved. Contacts: <gtalk@butenkoms.space> 5# 6# Licensed under the Apache License, Version 2.0 (the "License"); 7# you may not use this file except in compliance with the License. 8# You may obtain a copy of the License at 9# 10# http://www.apache.org/licenses/LICENSE-2.0 11# 12# Unless required by applicable law or agreed to in writing, software 13# distributed under the License is distributed on an "AS IS" BASIS, 14# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15# See the License for the specific language governing permissions and 16# limitations under the License. 17 18import time 19from enum import Enum 20from time import time 21from typing import Optional, Union 22perf_counter = process_time = time 23 24try: 25 from cengal.time_management.cpu_clock_cycles import perf_counter 26except ImportError: 27 try: 28 from time import perf_counter 29 except ImportError: 30 pass 31 32try: 33 from time import process_time 34except ImportError: 35 pass 36 37""" 38Module Docstring 39Docstrings: http://www.python.org/dev/peps/pep-0257/ 40""" 41 42__author__ = "ButenkoMS <gtalk@butenkoms.space>" 43__copyright__ = "Copyright © 2012-2024 ButenkoMS. All rights reserved. Contacts: <gtalk@butenkoms.space>" 44__credits__ = ["ButenkoMS <gtalk@butenkoms.space>", ] 45__license__ = "Apache License, Version 2.0" 46__version__ = "4.4.1" 47__maintainer__ = "ButenkoMS <gtalk@butenkoms.space>" 48__email__ = "gtalk@butenkoms.space" 49# __status__ = "Prototype" 50__status__ = "Development" 51# __status__ = "Production" 52 53 54class TimeLimitIsTooSmall(Exception): 55 def __init__(self, min_time: Optional[Union[float, int]], *args: object) -> None: 56 super().__init__(*args) 57 self.min_time: Optional[Union[float, int]] = min_time 58 59 60# TODO: add support for cpu_ticks_count 61class ClockType(Enum): 62 fake = 0 63 clock = 1 64 perf_counter = 2 65 process_time = 3 66 67 68def _fake(): 69 return 0 70 71 72class BaseTracer: 73 """ 74 Base class of all tracers 75 76 Lets assume you have a tracer: 77 78 tr = Tracer(10.0) 79 80 Or a fake tracer: 81 82 tr = TracerCounter(10000, 10.0) 83 84 As result you can use next interfaces 85 86 tr() # Will return True if tracer has finished it's counting and as a result, the specified time was passed. 87 88 tr.iter_per_time_unit # Will return counted time of iterations per second (if time() function uses second 89 as a time unit) 90 91 tr.iterations_made # Will return number of all iterations made (not including those that were produced after 92 the end of the counting) 93 94 tr.total_number_of_iterations_made # Will return number of all iterations made (including those that were 95 produced after the end of the counting) 96 97 tr.time_spent # Will return time spent (not including time that were used after the end of the counting) 98 99 tr.total_amount_of_time_spent # Will return time spent (including time that were used after the end of the 100 counting) 101 102 tr.clock_type # Will return used time function type (ClockType enum) 103 104 """ 105 106 def __init__(self, run_time: float, clock_type: ClockType=ClockType.perf_counter): 107 self.iter = None 108 self._number_of_iterations = 0 109 self._last_tracked_number_of_iterations = 0 110 self._start_time = None 111 self._end_time = None 112 self._relevant_stop_time = None 113 self._last_run_was_made = False 114 self._clock_type = clock_type 115 self._clock = None 116 self._init_clock() 117 self._run_time = run_time 118 if 0.0 == self._run_time: 119 raise TimeLimitIsTooSmall(None) 120 121 def __call__(self, *args, **kwargs): 122 return self._last_run_was_made 123 124 def _init_clock(self): 125 if ClockType.fake == self._clock_type: 126 self._clock = _fake 127 elif ClockType.clock == self._clock_type: 128 self._clock = time 129 elif ClockType.perf_counter == self._clock_type: 130 self._clock = perf_counter 131 elif ClockType.process_time == self._clock_type: 132 self._clock = process_time 133 134 @property 135 def iter_per_time_unit(self): 136 raise NotImplemented() 137 138 @property 139 def iterations_made(self): 140 return self._last_tracked_number_of_iterations 141 142 @property 143 def total_number_of_iterations_made(self): 144 return self._number_of_iterations 145 146 @property 147 def time_spent(self): 148 return self._relevant_stop_time - self._start_time 149 150 @property 151 def total_amount_of_time_spent(self): 152 return self._end_time - self._start_time 153 154 @property 155 def clock_type(self) -> ClockType: 156 return self._clock_type 157 158 @clock_type.setter 159 def clock_type(self, value: ClockType): 160 self._clock_type = value 161 self._init_clock() 162 163 164class Tracer(BaseTracer): 165 """ 166 Main tracer. 167 Its task is to find out the speed of code execution, and to stop the counting at about the specified time. 168 169 Example of use: 170 171 tr = Tracer(10.0) 172 while tr.iter(): 173 i = '456' 174 k = int('1243' + i) 175 176 print('{} iter/s; {} seconds; {} iterations'.format(tr.iter_per_time_unit, tr.time_spent, tr.iterations_made)) 177 178 """ 179 180 def __init__(self, run_time: float, clock_type: ClockType=ClockType.perf_counter): 181 super().__init__(run_time, clock_type) 182 self._testing_worker = self._test_runs 183 self._half_of_the_run_time = self._run_time / 2 184 if 0.0 == self._half_of_the_run_time: 185 raise TimeLimitIsTooSmall(None) 186 self._relevant_start_time = None 187 self._relevant_number_of_iterations_at_start = 0 188 self._relevant_number_of_iterations_at_end = 0 189 self._next_test_stop_on = 1 190 self.iter = self._first_run 191 192 @property 193 def iter_per_time_unit(self) -> float: 194 if self._last_run_was_made: 195 divider = self._relevant_stop_time - self._relevant_start_time 196 if 0 != divider: 197 return (self._relevant_number_of_iterations_at_end - self._relevant_number_of_iterations_at_start) \ 198 / divider 199 return 0 200 else: 201 divider = self._end_time - self._start_time 202 if 0 != divider: 203 return self._last_tracked_number_of_iterations / divider 204 return 0 205 206 def _first_run(self) -> bool: 207 self._number_of_iterations += 1 208 self._relevant_start_time = self._start_time = self._clock() 209 self.iter = self._subsequent_runs 210 return self._test_sub_runs(self._start_time) 211 212 def _subsequent_runs(self) -> bool: 213 self._number_of_iterations += 1 214 if self._number_of_iterations >= self._next_test_stop_on: 215 return self._testing_worker() 216 return True 217 218 def _test_runs(self) -> bool: 219 return self._test_sub_runs(self._clock()) 220 221 def _test_sub_runs(self, current_time) -> bool: 222 self._relevant_stop_time = self._end_time = current_time 223 self._last_tracked_number_of_iterations = self._number_of_iterations 224 delta_time = current_time - self._start_time 225 if delta_time >= self._half_of_the_run_time: 226 time_left = self._run_time - delta_time 227 # No need to: 228 # if time_left < 0: 229 # time_left = 0 230 iterations_per_second = self._number_of_iterations / delta_time 231 iterations_left = iterations_per_second * time_left 232 if iterations_left > 0: 233 self._next_test_stop_on = self._number_of_iterations + round(iterations_left) 234 self._testing_worker = self._last_run 235 self._relevant_start_time = current_time 236 self._relevant_number_of_iterations_at_start = self._number_of_iterations 237 return True 238 else: 239 return self._last_sub_run(current_time) 240 self._next_test_stop_on *= 2 241 return True 242 243 def _last_run(self) -> bool: 244 return self._last_sub_run(self._clock()) 245 246 def _last_sub_run(self, current_time) -> bool: 247 self._end_time = current_time 248 self._last_tracked_number_of_iterations = self._number_of_iterations 249 self._relevant_stop_time = self._end_time 250 self._relevant_number_of_iterations_at_end = self._number_of_iterations 251 self._testing_worker = self._after_last_runs 252 self._last_run_was_made = True 253 return False 254 255 def _after_last_runs(self) -> bool: 256 self._end_time = self._clock() 257 return False 258 259 260class GreedyTracer(BaseTracer): 261 """ 262 Greedy Main tracer. 263 Its task is to find out the speed of code execution, and to stop the counting at about the specified time. 264 The difference is that he checks time every single iteration. 265 266 Example of use is the same as for the Tracer() 267 268 """ 269 270 def __init__(self, run_time: float, clock_type=ClockType.perf_counter): 271 super().__init__(run_time, clock_type) 272 self.iter = self._first_run 273 274 def _first_run(self) -> bool: 275 self._start_time = self._clock() 276 self.iter = self._subsequent_runs 277 return self._subsequent_runs() 278 279 def _subsequent_runs(self) -> bool: 280 self._relevant_stop_time = self._end_time = self._clock() 281 self._number_of_iterations += 1 282 self._last_tracked_number_of_iterations = self._number_of_iterations 283 284 if (self._relevant_stop_time - self._start_time) < self._run_time: 285 return True 286 else: 287 self._last_run_was_made = True 288 self.iter = self._after_last_runs 289 return False 290 291 def _after_last_runs(self) -> bool: 292 self._number_of_iterations += 1 293 self._end_time = self._clock() 294 return False 295 296 @property 297 def iter_per_time_unit(self) -> float: 298 divider = self._relevant_stop_time - self._start_time 299 if 0 != divider: 300 return self._last_tracked_number_of_iterations / divider 301 return 0 302 303 304class TracerCounter(BaseTracer): 305 """ 306 Counting tracer. Pseudo-tracer. 307 Its don't have an overhead of periodic calling time() function. 308 Its task is to count down within a given time, using the speed information already counted by the real tracer 309 (by the Tracer class). 310 311 Example of use: 312 313 trc = TracerCounter(10000, 10.0) 314 while trc.iter(): 315 i = '456' 316 k = int('1243' + i) 317 318 print('{} iter/s; {} seconds; {} iters'.format(trc.iter_per_time_unit, trc.time_spent, trc.iterations_made)) 319 320 or: 321 def made_tests() -> Tracer: 322 tr = Tracer(0.1) # Run for about 0.1 of second. 323 while tr.iter(): 324 some_my_code() 325 return tr 326 327 def run(run_time: float, tests_result: Tracer): 328 trc = TracerCounter(tests_result.iter_per_time_unit, run_time) 329 while trc.iter(): 330 some_my_code() 331 332 print('{} iter/s; {} seconds; {} iterations'.format(trc.iter_per_time_unit, trc.time_spent, 333 trc.iterations_made)) 334 335 def main(): 336 tests_result = made_tests() 337 ... 338 while True: 339 time_to_rur_str = input('Enter run time: ') 340 if not time_to_run_str: 341 break 342 run(float(time_to_rur_str), tests_result) 343 344 """ 345 346 def __init__(self, iter_per_time_unit: float, run_time: float, clock_type=ClockType.fake): 347 super().__init__(run_time, clock_type) 348 self._iter_per_time_unit = iter_per_time_unit 349 self._number_of_iterations_needed = round(self._iter_per_time_unit * self._run_time) 350 self.iter = self._first_run 351 352 def _first_run(self) -> bool: 353 self._start_time = self._clock() 354 self.iter = self._subsequent_runs 355 return self._subsequent_runs() 356 357 def _subsequent_runs(self) -> bool: 358 self._number_of_iterations += 1 359 self._last_tracked_number_of_iterations = self._number_of_iterations 360 if self._number_of_iterations < self._number_of_iterations_needed: 361 return True 362 else: 363 self._relevant_stop_time = self._end_time = self._clock() 364 self._last_run_was_made = True 365 self.iter = self._after_last_runs 366 return False 367 368 def _after_last_runs(self) -> bool: 369 self._number_of_iterations += 1 370 self._end_time = self._clock() 371 return False 372 373 @property 374 def iter_per_time_unit(self) -> float: 375 if self._last_run_was_made: 376 divider = self._relevant_stop_time - self._start_time 377 if 0 != divider: 378 return self._last_tracked_number_of_iterations / divider 379 return 0 380 else: 381 return self._iter_per_time_unit 382 383 384class TracerIterator: 385 """ 386 An iterator class. It converts any type of given tracer into an iterator. 387 388 As result you have an option to use constructions like this: 389 390 for i in TracerIterator(Tracer(20.0)): 391 k = int('1243') 392 393 But keep in mind that in this case there will be a bigger overhead. And there will be less CPU time for the payload. 394 395 """ 396 397 def __init__(self, tracer: BaseTracer): 398 self._tracer = tracer 399 400 def __iter__(self): 401 return self 402 403 def __next__(self): 404 if self._tracer.iter(): 405 return self._tracer.iterations_made 406 else: 407 raise StopIteration() 408 409 next = __next__ 410 411 @property 412 def tracer(self): 413 return self._tracer
55class TimeLimitIsTooSmall(Exception): 56 def __init__(self, min_time: Optional[Union[float, int]], *args: object) -> None: 57 super().__init__(*args) 58 self.min_time: Optional[Union[float, int]] = min_time
Common base class for all non-exit exceptions.
Inherited Members
- builtins.BaseException
- with_traceback
- args
An enumeration.
Inherited Members
- enum.Enum
- name
- value
73class BaseTracer: 74 """ 75 Base class of all tracers 76 77 Lets assume you have a tracer: 78 79 tr = Tracer(10.0) 80 81 Or a fake tracer: 82 83 tr = TracerCounter(10000, 10.0) 84 85 As result you can use next interfaces 86 87 tr() # Will return True if tracer has finished it's counting and as a result, the specified time was passed. 88 89 tr.iter_per_time_unit # Will return counted time of iterations per second (if time() function uses second 90 as a time unit) 91 92 tr.iterations_made # Will return number of all iterations made (not including those that were produced after 93 the end of the counting) 94 95 tr.total_number_of_iterations_made # Will return number of all iterations made (including those that were 96 produced after the end of the counting) 97 98 tr.time_spent # Will return time spent (not including time that were used after the end of the counting) 99 100 tr.total_amount_of_time_spent # Will return time spent (including time that were used after the end of the 101 counting) 102 103 tr.clock_type # Will return used time function type (ClockType enum) 104 105 """ 106 107 def __init__(self, run_time: float, clock_type: ClockType=ClockType.perf_counter): 108 self.iter = None 109 self._number_of_iterations = 0 110 self._last_tracked_number_of_iterations = 0 111 self._start_time = None 112 self._end_time = None 113 self._relevant_stop_time = None 114 self._last_run_was_made = False 115 self._clock_type = clock_type 116 self._clock = None 117 self._init_clock() 118 self._run_time = run_time 119 if 0.0 == self._run_time: 120 raise TimeLimitIsTooSmall(None) 121 122 def __call__(self, *args, **kwargs): 123 return self._last_run_was_made 124 125 def _init_clock(self): 126 if ClockType.fake == self._clock_type: 127 self._clock = _fake 128 elif ClockType.clock == self._clock_type: 129 self._clock = time 130 elif ClockType.perf_counter == self._clock_type: 131 self._clock = perf_counter 132 elif ClockType.process_time == self._clock_type: 133 self._clock = process_time 134 135 @property 136 def iter_per_time_unit(self): 137 raise NotImplemented() 138 139 @property 140 def iterations_made(self): 141 return self._last_tracked_number_of_iterations 142 143 @property 144 def total_number_of_iterations_made(self): 145 return self._number_of_iterations 146 147 @property 148 def time_spent(self): 149 return self._relevant_stop_time - self._start_time 150 151 @property 152 def total_amount_of_time_spent(self): 153 return self._end_time - self._start_time 154 155 @property 156 def clock_type(self) -> ClockType: 157 return self._clock_type 158 159 @clock_type.setter 160 def clock_type(self, value: ClockType): 161 self._clock_type = value 162 self._init_clock()
Base class of all tracers
Lets assume you have a tracer:
tr = Tracer(10.0)
Or a fake tracer:
tr = TracerCounter(10000, 10.0)
As result you can use next interfaces
tr() # Will return True if tracer has finished it's counting and as a result, the specified time was passed.
tr.iter_per_time_unit # Will return counted time of iterations per second (if time() function uses second
as a time unit)
tr.iterations_made # Will return number of all iterations made (not including those that were produced after
the end of the counting)
tr.total_number_of_iterations_made # Will return number of all iterations made (including those that were
produced after the end of the counting)
tr.time_spent # Will return time spent (not including time that were used after the end of the counting)
tr.total_amount_of_time_spent # Will return time spent (including time that were used after the end of the
counting)
tr.clock_type # Will return used time function type (ClockType enum)
107 def __init__(self, run_time: float, clock_type: ClockType=ClockType.perf_counter): 108 self.iter = None 109 self._number_of_iterations = 0 110 self._last_tracked_number_of_iterations = 0 111 self._start_time = None 112 self._end_time = None 113 self._relevant_stop_time = None 114 self._last_run_was_made = False 115 self._clock_type = clock_type 116 self._clock = None 117 self._init_clock() 118 self._run_time = run_time 119 if 0.0 == self._run_time: 120 raise TimeLimitIsTooSmall(None)
165class Tracer(BaseTracer): 166 """ 167 Main tracer. 168 Its task is to find out the speed of code execution, and to stop the counting at about the specified time. 169 170 Example of use: 171 172 tr = Tracer(10.0) 173 while tr.iter(): 174 i = '456' 175 k = int('1243' + i) 176 177 print('{} iter/s; {} seconds; {} iterations'.format(tr.iter_per_time_unit, tr.time_spent, tr.iterations_made)) 178 179 """ 180 181 def __init__(self, run_time: float, clock_type: ClockType=ClockType.perf_counter): 182 super().__init__(run_time, clock_type) 183 self._testing_worker = self._test_runs 184 self._half_of_the_run_time = self._run_time / 2 185 if 0.0 == self._half_of_the_run_time: 186 raise TimeLimitIsTooSmall(None) 187 self._relevant_start_time = None 188 self._relevant_number_of_iterations_at_start = 0 189 self._relevant_number_of_iterations_at_end = 0 190 self._next_test_stop_on = 1 191 self.iter = self._first_run 192 193 @property 194 def iter_per_time_unit(self) -> float: 195 if self._last_run_was_made: 196 divider = self._relevant_stop_time - self._relevant_start_time 197 if 0 != divider: 198 return (self._relevant_number_of_iterations_at_end - self._relevant_number_of_iterations_at_start) \ 199 / divider 200 return 0 201 else: 202 divider = self._end_time - self._start_time 203 if 0 != divider: 204 return self._last_tracked_number_of_iterations / divider 205 return 0 206 207 def _first_run(self) -> bool: 208 self._number_of_iterations += 1 209 self._relevant_start_time = self._start_time = self._clock() 210 self.iter = self._subsequent_runs 211 return self._test_sub_runs(self._start_time) 212 213 def _subsequent_runs(self) -> bool: 214 self._number_of_iterations += 1 215 if self._number_of_iterations >= self._next_test_stop_on: 216 return self._testing_worker() 217 return True 218 219 def _test_runs(self) -> bool: 220 return self._test_sub_runs(self._clock()) 221 222 def _test_sub_runs(self, current_time) -> bool: 223 self._relevant_stop_time = self._end_time = current_time 224 self._last_tracked_number_of_iterations = self._number_of_iterations 225 delta_time = current_time - self._start_time 226 if delta_time >= self._half_of_the_run_time: 227 time_left = self._run_time - delta_time 228 # No need to: 229 # if time_left < 0: 230 # time_left = 0 231 iterations_per_second = self._number_of_iterations / delta_time 232 iterations_left = iterations_per_second * time_left 233 if iterations_left > 0: 234 self._next_test_stop_on = self._number_of_iterations + round(iterations_left) 235 self._testing_worker = self._last_run 236 self._relevant_start_time = current_time 237 self._relevant_number_of_iterations_at_start = self._number_of_iterations 238 return True 239 else: 240 return self._last_sub_run(current_time) 241 self._next_test_stop_on *= 2 242 return True 243 244 def _last_run(self) -> bool: 245 return self._last_sub_run(self._clock()) 246 247 def _last_sub_run(self, current_time) -> bool: 248 self._end_time = current_time 249 self._last_tracked_number_of_iterations = self._number_of_iterations 250 self._relevant_stop_time = self._end_time 251 self._relevant_number_of_iterations_at_end = self._number_of_iterations 252 self._testing_worker = self._after_last_runs 253 self._last_run_was_made = True 254 return False 255 256 def _after_last_runs(self) -> bool: 257 self._end_time = self._clock() 258 return False
Main tracer. Its task is to find out the speed of code execution, and to stop the counting at about the specified time.
Example of use:
tr = Tracer(10.0)
while tr.iter():
i = '456'
k = int('1243' + i)
print('{} iter/s; {} seconds; {} iterations'.format(tr.iter_per_time_unit, tr.time_spent, tr.iterations_made))
181 def __init__(self, run_time: float, clock_type: ClockType=ClockType.perf_counter): 182 super().__init__(run_time, clock_type) 183 self._testing_worker = self._test_runs 184 self._half_of_the_run_time = self._run_time / 2 185 if 0.0 == self._half_of_the_run_time: 186 raise TimeLimitIsTooSmall(None) 187 self._relevant_start_time = None 188 self._relevant_number_of_iterations_at_start = 0 189 self._relevant_number_of_iterations_at_end = 0 190 self._next_test_stop_on = 1 191 self.iter = self._first_run
193 @property 194 def iter_per_time_unit(self) -> float: 195 if self._last_run_was_made: 196 divider = self._relevant_stop_time - self._relevant_start_time 197 if 0 != divider: 198 return (self._relevant_number_of_iterations_at_end - self._relevant_number_of_iterations_at_start) \ 199 / divider 200 return 0 201 else: 202 divider = self._end_time - self._start_time 203 if 0 != divider: 204 return self._last_tracked_number_of_iterations / divider 205 return 0
261class GreedyTracer(BaseTracer): 262 """ 263 Greedy Main tracer. 264 Its task is to find out the speed of code execution, and to stop the counting at about the specified time. 265 The difference is that he checks time every single iteration. 266 267 Example of use is the same as for the Tracer() 268 269 """ 270 271 def __init__(self, run_time: float, clock_type=ClockType.perf_counter): 272 super().__init__(run_time, clock_type) 273 self.iter = self._first_run 274 275 def _first_run(self) -> bool: 276 self._start_time = self._clock() 277 self.iter = self._subsequent_runs 278 return self._subsequent_runs() 279 280 def _subsequent_runs(self) -> bool: 281 self._relevant_stop_time = self._end_time = self._clock() 282 self._number_of_iterations += 1 283 self._last_tracked_number_of_iterations = self._number_of_iterations 284 285 if (self._relevant_stop_time - self._start_time) < self._run_time: 286 return True 287 else: 288 self._last_run_was_made = True 289 self.iter = self._after_last_runs 290 return False 291 292 def _after_last_runs(self) -> bool: 293 self._number_of_iterations += 1 294 self._end_time = self._clock() 295 return False 296 297 @property 298 def iter_per_time_unit(self) -> float: 299 divider = self._relevant_stop_time - self._start_time 300 if 0 != divider: 301 return self._last_tracked_number_of_iterations / divider 302 return 0
Greedy Main tracer. Its task is to find out the speed of code execution, and to stop the counting at about the specified time. The difference is that he checks time every single iteration.
Example of use is the same as for the Tracer()
305class TracerCounter(BaseTracer): 306 """ 307 Counting tracer. Pseudo-tracer. 308 Its don't have an overhead of periodic calling time() function. 309 Its task is to count down within a given time, using the speed information already counted by the real tracer 310 (by the Tracer class). 311 312 Example of use: 313 314 trc = TracerCounter(10000, 10.0) 315 while trc.iter(): 316 i = '456' 317 k = int('1243' + i) 318 319 print('{} iter/s; {} seconds; {} iters'.format(trc.iter_per_time_unit, trc.time_spent, trc.iterations_made)) 320 321 or: 322 def made_tests() -> Tracer: 323 tr = Tracer(0.1) # Run for about 0.1 of second. 324 while tr.iter(): 325 some_my_code() 326 return tr 327 328 def run(run_time: float, tests_result: Tracer): 329 trc = TracerCounter(tests_result.iter_per_time_unit, run_time) 330 while trc.iter(): 331 some_my_code() 332 333 print('{} iter/s; {} seconds; {} iterations'.format(trc.iter_per_time_unit, trc.time_spent, 334 trc.iterations_made)) 335 336 def main(): 337 tests_result = made_tests() 338 ... 339 while True: 340 time_to_rur_str = input('Enter run time: ') 341 if not time_to_run_str: 342 break 343 run(float(time_to_rur_str), tests_result) 344 345 """ 346 347 def __init__(self, iter_per_time_unit: float, run_time: float, clock_type=ClockType.fake): 348 super().__init__(run_time, clock_type) 349 self._iter_per_time_unit = iter_per_time_unit 350 self._number_of_iterations_needed = round(self._iter_per_time_unit * self._run_time) 351 self.iter = self._first_run 352 353 def _first_run(self) -> bool: 354 self._start_time = self._clock() 355 self.iter = self._subsequent_runs 356 return self._subsequent_runs() 357 358 def _subsequent_runs(self) -> bool: 359 self._number_of_iterations += 1 360 self._last_tracked_number_of_iterations = self._number_of_iterations 361 if self._number_of_iterations < self._number_of_iterations_needed: 362 return True 363 else: 364 self._relevant_stop_time = self._end_time = self._clock() 365 self._last_run_was_made = True 366 self.iter = self._after_last_runs 367 return False 368 369 def _after_last_runs(self) -> bool: 370 self._number_of_iterations += 1 371 self._end_time = self._clock() 372 return False 373 374 @property 375 def iter_per_time_unit(self) -> float: 376 if self._last_run_was_made: 377 divider = self._relevant_stop_time - self._start_time 378 if 0 != divider: 379 return self._last_tracked_number_of_iterations / divider 380 return 0 381 else: 382 return self._iter_per_time_unit
Counting tracer. Pseudo-tracer. Its don't have an overhead of periodic calling time() function. Its task is to count down within a given time, using the speed information already counted by the real tracer (by the Tracer class).
Example of use:
trc = TracerCounter(10000, 10.0)
while trc.iter():
i = '456'
k = int('1243' + i)
print('{} iter/s; {} seconds; {} iters'.format(trc.iter_per_time_unit, trc.time_spent, trc.iterations_made))
or: def made_tests() -> Tracer: tr = Tracer(0.1) # Run for about 0.1 of second. while tr.iter(): some_my_code() return tr
def run(run_time: float, tests_result: Tracer):
trc = TracerCounter(tests_result.iter_per_time_unit, run_time)
while trc.iter():
some_my_code()
print('{} iter/s; {} seconds; {} iterations'.format(trc.iter_per_time_unit, trc.time_spent,
trc.iterations_made))
def main():
tests_result = made_tests()
...
while True:
time_to_rur_str = input('Enter run time: ')
if not time_to_run_str:
break
run(float(time_to_rur_str), tests_result)
347 def __init__(self, iter_per_time_unit: float, run_time: float, clock_type=ClockType.fake): 348 super().__init__(run_time, clock_type) 349 self._iter_per_time_unit = iter_per_time_unit 350 self._number_of_iterations_needed = round(self._iter_per_time_unit * self._run_time) 351 self.iter = self._first_run
385class TracerIterator: 386 """ 387 An iterator class. It converts any type of given tracer into an iterator. 388 389 As result you have an option to use constructions like this: 390 391 for i in TracerIterator(Tracer(20.0)): 392 k = int('1243') 393 394 But keep in mind that in this case there will be a bigger overhead. And there will be less CPU time for the payload. 395 396 """ 397 398 def __init__(self, tracer: BaseTracer): 399 self._tracer = tracer 400 401 def __iter__(self): 402 return self 403 404 def __next__(self): 405 if self._tracer.iter(): 406 return self._tracer.iterations_made 407 else: 408 raise StopIteration() 409 410 next = __next__ 411 412 @property 413 def tracer(self): 414 return self._tracer
An iterator class. It converts any type of given tracer into an iterator.
As result you have an option to use constructions like this:
for i in TracerIterator(Tracer(20.0)):
k = int('1243')
But keep in mind that in this case there will be a bigger overhead. And there will be less CPU time for the payload.