Source code for cpyquickhelper.numbers.speed_measure

"""
Measures speed.


:githublink:`%|py|5`
"""
import sys
from timeit import Timer


[docs]def measure_time(stmt, context, repeat=10, number=50, div_by_number=False): """ Measures a statement and returns the results as a dictionary. :param stmt: string :param context: variable to know in a dictionary :param repeat: average over *repeat* experiment :param number: number of executions in one row :param div_by_number: divide by the number of executions :return: dictionary .. runpython:: :showcode: from cpyquickhelper.numbers import measure_time from math import cos res = measure_time("cos(x)", context=dict(cos=cos, x=5.)) print(res) See `Timer.repeat <https://docs.python.org/3/library/timeit.html?timeit.Timer.repeat>`_ for a better understanding of parameter *repeat* and *number*. The function returns a duration corresponding to *number* times the execution of the main statement. :githublink:`%|py|33` """ import numpy # pylint: disable=C0415 tim = Timer(stmt, globals=context) res = numpy.array(tim.repeat(repeat=repeat, number=number)) if div_by_number: res /= number mean = numpy.mean(res) dev = numpy.mean(res ** 2) dev = (dev - mean**2) ** 0.5 mes = dict(average=mean, deviation=dev, min_exec=numpy.min(res), max_exec=numpy.max(res), repeat=repeat, number=number) if 'values' in context: if hasattr(context['values'], 'shape'): mes['size'] = context['values'].shape[0] else: mes['size'] = len(context['values']) # pragma: no cover else: mes['context_size'] = sys.getsizeof(context) return mes
[docs]def _fcts(): """ Returns functions to measure. :githublink:`%|py|57` """ import numpy # pylint: disable=C0415 from .cbenchmark_dot import vector_dot_product # pylint: disable=E0611,C0415 from .cbenchmark_dot import vector_dot_product16 # pylint: disable=E0611,C0415 from .cbenchmark_dot import vector_dot_product16_nofcall # pylint: disable=E0611,C0415 from .cbenchmark_dot import vector_dot_product16_sse # pylint: disable=E0611,C0415 def simple_dot(values): return numpy.dot(values, values) def c11_dot(vect): return vector_dot_product(vect, vect) def c11_dot16(vect): return vector_dot_product16(vect, vect) def c11_dot16_nofcall(vect): return vector_dot_product16_nofcall(vect, vect) def c11_dot16_sse(vect): return vector_dot_product16_sse(vect, vect) return [simple_dot, c11_dot, c11_dot16, c11_dot16_nofcall, c11_dot16_sse]
[docs]def check_speed(dims=[100000], repeat=10, number=50, fLOG=print): # pylint: disable=W0102 """ Prints out some information about speed computation of this laptop. See :ref:`cbenchmarkbranchingrst` to compare. :param dims: sets of dimensions to try :param repeat: average over *repeat* experiment :param number: number of execution in one row :param fLOG: logging function :return: iterator on results :epkg:`numpy` is multithreaded. For an accurate comparison, this needs to be disabled. This can be done by setting environment variable ``MKL_NUM_THREADS=1`` or by running: :: import mkl mkl.set_num_threads(1) .. index:: MKL_NUM_THREADS One example of use: .. runpython:: :showcode: from cpyquickhelper.numbers import check_speed res = list(check_speed(dims=[100, 1000])) import pprint pprint.pprint(res) :githublink:`%|py|113` """ import numpy # pylint: disable=C0415 fcts = _fcts() mx = max(dims) vect = numpy.ones((mx,)) for i in range(0, vect.shape[0]): vect[i] = i for i in dims: values = vect[:i].copy() for fct in fcts: ct = {fct.__name__: fct} ct['values'] = values t = measure_time("{0}(values)".format(fct.__name__), repeat=repeat, number=number, context=ct) t['name'] = fct.__name__ if fLOG: fLOG(t) yield t