Self-implementation of something like% timeit, a magic command of jupyter that is convenient for speed measurement, in Python

things to do

Implement something like% timeit in jupyter. I want to use the return value of this as a variable.

ipynb


%timeit -n 10 -r 100 test()

There are options other than -n and -r, but this time we will not implement other than these two.

What are you doing with % timeit -n 10 -r 100 test () in the first place?

  1. Repeat test () 100 times and return the value with the fastest execution speed.
  2. Repeat 1 10 times and take the average.

In other words, it gives ** the fastest average of 10 pieces **.

Is timeit in the standard library useless?

  1. Repeat test () 100 times and return the value with the fastest execution speed.

↑ Isn't there a method to do this? For the time being, I will try to implement it myself as well as studying.

https://docs.python.org/ja/3/library/timeit.html

Directory structure

.
├── utils
│   ├── speed_test.py
│   └── __init__.py
└── main.py

code

module

speed_test.py


import time


class Measurer(object):
    def mean_time(self, num=10):
        """
A decorator that returns the average of the results of running num times.
        """
        def outer_wrapper(func):
            def wrapper(*args, **kwargs):
                fast_time_list = [func(*args, **kwargs) for _ in range(num)]
                mean = sum(fast_time_list) / len(fast_time_list)
                return mean
            return wrapper
        return outer_wrapper

    def fast_time(self, repeat=10):
        """
The minimum value (the fastest execution speed) among the repeated executions)A decorator that returns.
        """
        def outer_wrapper(func):
            def wrapper(*args, **kwargs):
                result_list = [func(*args, **kwargs) for _ in range(repeat)]
                # print(result_list)
                min_time = min(result_list)
                # print(result_list)
                # print(min_time)
                return min_time
            return wrapper
        return outer_wrapper

    def onece_time(self, func):
        """
A decorator that returns the execution speed of the function passed as an argument.
        """
        def wrapper(*args, **kwargs):
            # print('test start')
            start_time = time.time()
            func(*args, **kwargs)
            finish_time = time.time()
            elapsed_time = finish_time - start_time
            # print('elapsed_time => {:.10f}sec'.format(elapsed_time))
            # print('test finish')
            return elapsed_time
        return wrapper

    def execute(self, func, *args, num, repeat):
        """
        1.Calculates the fastest value among the repeated executions.
        2.Repeat 1 num times and return the average of num fastest values.
        """
        @self.mean_time(num=num)
        @self.fast_time(repeat=repeat)
        @self.onece_time
        def _execute(fn, *args):
            return fn(*args)
        return _execute(func, *args)

Executable file

main.py


from utils import speed_test


#Define a function for measurement
def test(max_count):
    count = 0
    for _ in range(max_count):
        count += 1


def main():
    max_count = 100
    num = 10
    repeat = 100

    measurer = speed_test.Measurer()
    #After the second argument, you can pass multiple arguments with variable length
    result = measurer.execute(test, max_count, num=num, repeat=repeat)
    print('result -> {:.12f}'.format(result))


if __name__ == '__main__':
    main()

Pattern to visualize

Since the return value can be taken, it is easy to visualize and compare.

py:main.py


import pandas as pd
import matplotlib.pyplot as plt
from IPython.display import display

from utils import speed_test


def test1(str_list):
    """
Numerical conversion of all elements of the character string list ①
    """
    int_list = [int(i) for i in str_list]


def test2(str_list):
    """
Numerically convert all elements of the character string list ②
    """
    int_list = list(map(int, str_list))


def main():
    num = 10
    repeat = 100

    #Generate string list
    str_list = [str(i) for i in range(10000)]
    # ['0', '1', '2', ... '9997', '9998', '9999']

    measurer = speed_test.Measurer()
    #After the second argument, you can pass multiple arguments with variable length
    result1 = measurer.execute(test1, str_list, num=num, repeat=repeat)
    result2 = measurer.execute(test2, str_list, num=num, repeat=repeat)
    # print('result -> {:.12f}'.format(result))

    df = pd.DataFrame({
        'for': [result1],
        'map': [result2]
    })

    display(df)

    x = ['for', 'map']
    y = [result1, result2]
    plt.bar(x, y)
    plt.show


if __name__ == '__main__':
    main()
for	        map
0.001499	0.00109

名称未設定.png

Recommended Posts

Self-implementation of something like% timeit, a magic command of jupyter that is convenient for speed measurement, in Python
A memorandum of how to execute the! Sudo magic command in Jupyter Notebook
Linux is something like that in the first place
Existence check of external command in Python (like `which`)
A general-purpose program that formats Linux command strings in python
Do something like a Python interpreter in Visual Studio Code
[Django] A collection of scripts that are convenient for development
A set of script files that do wordcloud in Python3
Play a sound in Python assuming that the keyboard is a piano keyboard
A brief summary of Graphviz in python (explained only for mac)
A function that measures the processing time of a method in python
A program that determines whether a number entered in Python is a prime number
What's new in datetime that is a bit more useful in Python 3
Hit a command in Python (Windows)
Something like JS setTimeout in python
Something like tail -f in Python
A summary of Python e-books that are useful for free-to-read data analysis
Code reading of faker, a library that generates test data in Python
Code reading of Safe, a library for checking password strength in Python