Hot-keys on this page
r m x p toggle line displays
j k next/prev highlighted chunk
0 (zero) top of page
1 (one) first highlighted chunk
1"""
2@file
3@brief Measures speed.
4"""
5import sys
6from timeit import Timer
9def measure_time(stmt, context, repeat=10, number=50, div_by_number=False):
10 """
11 Measures a statement and returns the results as a dictionary.
13 @param stmt string
14 @param context variable to know in a dictionary
15 @param repeat average over *repeat* experiment
16 @param number number of executions in one row
17 @param div_by_number divide by the number of executions
18 @return dictionary
20 .. runpython::
21 :showcode:
23 from cpyquickhelper.numbers import measure_time
24 from math import cos
26 res = measure_time("cos(x)", context=dict(cos=cos, x=5.))
27 print(res)
29 See `Timer.repeat <https://docs.python.org/3/library/timeit.html?timeit.Timer.repeat>`_
30 for a better understanding of parameter *repeat* and *number*.
31 The function returns a duration corresponding to
32 *number* times the execution of the main statement.
33 """
34 import numpy # pylint: disable=C0415
35 tim = Timer(stmt, globals=context)
36 res = numpy.array(tim.repeat(repeat=repeat, number=number))
37 if div_by_number:
38 res /= number
39 mean = numpy.mean(res)
40 dev = numpy.mean(res ** 2)
41 dev = (dev - mean**2) ** 0.5
42 mes = dict(average=mean, deviation=dev, min_exec=numpy.min(res),
43 max_exec=numpy.max(res), repeat=repeat, number=number)
44 if 'values' in context:
45 if hasattr(context['values'], 'shape'):
46 mes['size'] = context['values'].shape[0]
47 else:
48 mes['size'] = len(context['values']) # pragma: no cover
49 else:
50 mes['context_size'] = sys.getsizeof(context)
51 return mes
54def _fcts():
55 """
56 Returns functions to measure.
57 """
58 import numpy # pylint: disable=C0415
59 from .cbenchmark_dot import vector_dot_product # pylint: disable=E0611,C0415
60 from .cbenchmark_dot import vector_dot_product16 # pylint: disable=E0611,C0415
61 from .cbenchmark_dot import vector_dot_product16_nofcall # pylint: disable=E0611,C0415
62 from .cbenchmark_dot import vector_dot_product16_sse # pylint: disable=E0611,C0415
64 def simple_dot(values):
65 return numpy.dot(values, values)
67 def c11_dot(vect):
68 return vector_dot_product(vect, vect)
70 def c11_dot16(vect):
71 return vector_dot_product16(vect, vect)
73 def c11_dot16_nofcall(vect):
74 return vector_dot_product16_nofcall(vect, vect)
76 def c11_dot16_sse(vect):
77 return vector_dot_product16_sse(vect, vect)
79 return [simple_dot, c11_dot, c11_dot16, c11_dot16_nofcall, c11_dot16_sse]
82def check_speed(dims=[100000], repeat=10, number=50, fLOG=print): # pylint: disable=W0102
83 """
84 Prints out some information about speed computation
85 of this laptop. See :ref:`cbenchmarkbranchingrst` to compare.
87 @param dims sets of dimensions to try
88 @param repeat average over *repeat* experiment
89 @param number number of execution in one row
90 @param fLOG logging function
91 @return iterator on results
93 :epkg:`numpy` is multithreaded. For an accurate comparison,
94 this needs to be disabled. This can be done by setting environment variable
95 ``MKL_NUM_THREADS=1`` or by running:
97 ::
99 import mkl
100 mkl.set_num_threads(1)
102 .. index:: MKL_NUM_THREADS
104 One example of use:
106 .. runpython::
107 :showcode:
109 from cpyquickhelper.numbers import check_speed
110 res = list(check_speed(dims=[100, 1000]))
111 import pprint
112 pprint.pprint(res)
113 """
114 import numpy # pylint: disable=C0415
115 fcts = _fcts()
116 mx = max(dims)
117 vect = numpy.ones((mx,))
118 for i in range(0, vect.shape[0]):
119 vect[i] = i
120 for i in dims:
121 values = vect[:i].copy()
122 for fct in fcts:
123 ct = {fct.__name__: fct}
124 ct['values'] = values
125 t = measure_time("{0}(values)".format(fct.__name__),
126 repeat=repeat, number=number, context=ct)
127 t['name'] = fct.__name__
128 if fLOG:
129 fLOG(t)
130 yield t