Last active
September 9, 2024 06:56
-
-
Save ZenithClown/df4391a8b0313eb808e9a0f4ef5c78ad to your computer and use it in GitHub Desktop.
A Simple Python Decorator Function to Print the Runtime of a Function
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# -*- encoding: utf-8 -*- | |
""" | |
An Interface of Common Functions that Extends the Wrappers | |
The wrappers are a great way that provides information that can be | |
used for time and memory optimization. However, python does not | |
support inline decorator definations - more information is available | |
at `SO28245471 <https://stackoverflow.com/a/28245471/6623589>`_. | |
A context manager (``with``) can serve as a bridge between the | |
decorators and in-line capabilities of function execution | |
`GH#32 <https://github.com/sharkutilities/pandas-wizard/issues/32>`_. | |
""" | |
import time | |
class CatchTime(object): | |
""" | |
A Context Manager Interface for In-Line Time Calculation | |
The wrappers provided under ``pandaswizard`` are great way to | |
print execution time of a function - however, this lacks the | |
capability to calculate time for in-line python functions | |
like for example: | |
.. code-block:: python | |
import pandas as pd | |
# using wrapper approach to read csv and timeit | |
@pdw.wrappers.timeit | |
def read_csv_(*args, **kwargs) -> pd.DataFrame: | |
return pd.read_csv(*args, **kwargs) | |
However, this can be further enhanced and thus reducing time | |
to develop wrappers interfaces by using context managers lile: | |
.. code-block:: python | |
with CatchTime() as T: | |
data = pd.read_csv(...) | |
# another use case, using the context manager for apply | |
with CatchTime(): | |
data["calculation"] = data["column"].apply(...) | |
The context manager thus can act as a bridge for in-line function | |
application and print time. | |
:type fmt: str | |
:param fmt: Output format string with prefix is in-built, this | |
is a new addition to control the format from outside the | |
scope of the context manager. | |
""" | |
def __init__(self, fmt : str = "Executed in {:,.3f} secs."): | |
self.fmt = fmt | |
def __enter__(self) -> None: | |
self.start = time.perf_counter() | |
return self | |
def __exit__(self, exc_type, exc_value, exc_traceback) -> None: | |
print(self.fmt.format(self.elapsed)) | |
@property | |
def elapsed(self) -> float: | |
""" | |
Returns the Current Elapsed Time from the Function Start | |
The ``.elapsed`` property returns the in-between elapsed time | |
from the context manager's scope or can be used to store the | |
time at certain levels for time optimization. | |
When executed from the context manager's scope the function | |
returns the intermediate time, or returns the final executed | |
time when the context manager is closed. | |
.. code-block:: python | |
with CatchTime() as t: | |
# do something | |
print("Elapsed Time: {t.elapsed:.3f}") | |
# do something else | |
print("Elapsed Time: {t.elapsed:.3f}") | |
# the final execution time can be stored or printed | |
total_exec_time = t.elapsed | |
""" | |
return time.perf_counter() - self.start |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# -*- encoding: utf-8 -*- | |
__author__ = "Debmalya Pramanik" | |
__status__ = "production" | |
__version__ = "1.0" | |
__docformat__ = "camelCasing" | |
__copyright__ = "Copyright (c) 2020 Debmalya Pramanik | Indian Institute of Technology (IIT), Dhanbad" | |
__affiliation__ = "Reliance Industries Ltd." | |
import time | |
import functools | |
def timeit(func): | |
""" | |
A Mimic of the iPython Magic :attr:`%timeit` for Python Function | |
The built-in iPython magic function :attr:`%timeit` displays the | |
executed time of a function, or like the one from command line: | |
.. code-block:: shell | |
python -m timeit "function()" | |
The function creates a decorator which can be used to time and | |
analyze the execution time for any function by: | |
.. code-block:: python | |
@timeit | |
def some_function(): | |
# do some work | |
some_function() # execute the function with the decorator | |
> Run time for some_function: **** | |
The function is meant for general python function, for more | |
robus operation and using the same for ``pandas`` use the | |
``pandaswizard.wrappers.timeit`` - more information is available | |
`here <https://pandas-wizard.readthedocs.io/en/latest/index.html>`_. | |
The wrappers are a great way that provides information that can be | |
used for time and memory optimization. However, python does not | |
support inline decorator definations - more information is available | |
at `SO28245471 <https://stackoverflow.com/a/28245471/6623589>`_. | |
A context manager (``with``) can serve as a bridge between the | |
decorators and in-line capabilities of function execution | |
`GH#32 <https://github.com/sharkutilities/pandas-wizard/issues/32>`_. | |
""" | |
@functools.wraps(func) | |
def _wrapper(*args, **kwargs): # accepts all arguments | |
print(f"Executed with @timeit[`{func.__name__}`]") | |
start = time.process_time() # capture start time | |
_return = func(*args, **kwargs) # execute the actual function | |
process_time = time.process_time() - start | |
print(f"Function Executed in {process_time:,.3f} secs.") | |
return _return | |
return _wrapper |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment