1
"""
2
@file
3
@brief Measures speed.
4
"""
5 1
import sys
6 1
from timeit import Timer
7

8

9 1
def measure_time(stmt, context, repeat=10, number=50, div_by_number=False):
10
    """
11
    Measures a statement and returns the results as a dictionary.
12

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
19

20
    .. runpython::
21
        :showcode:
22

23
        from cpyquickhelper.numbers import measure_time
24
        from math import cos
25

26
        res = measure_time("cos(x)", context=dict(cos=cos, x=5.))
27
        print(res)
28

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 1
    import numpy  # pylint: disable=C0415
35 1
    tim = Timer(stmt, globals=context)
36 1
    res = numpy.array(tim.repeat(repeat=repeat, number=number))
37 1
    if div_by_number:
38 1
        res /= number
39 1
    mean = numpy.mean(res)
40 1
    dev = numpy.mean(res ** 2)
41 1
    dev = (dev - mean**2) ** 0.5
42 1
    mes = dict(average=mean, deviation=dev, min_exec=numpy.min(res),
43
               max_exec=numpy.max(res), repeat=repeat, number=number)
44 1
    if 'values' in context:
45 1
        if hasattr(context['values'], 'shape'):
46 1
            mes['size'] = context['values'].shape[0]
47
        else:
48
            mes['size'] = len(context['values'])  # pragma: no cover
49
    else:
50 1
        mes['context_size'] = sys.getsizeof(context)
51 1
    return mes
52

53

54 1
def _fcts():
55
    """
56
    Returns functions to measure.
57
    """
58 1
    import numpy  # pylint: disable=C0415
59 1
    from .cbenchmark_dot import vector_dot_product  # pylint: disable=E0611,C0415
60 1
    from .cbenchmark_dot import vector_dot_product16  # pylint: disable=E0611,C0415
61 1
    from .cbenchmark_dot import vector_dot_product16_nofcall  # pylint: disable=E0611,C0415
62 1
    from .cbenchmark_dot import vector_dot_product16_sse  # pylint: disable=E0611,C0415
63

64 1
    def simple_dot(values):
65 1
        return numpy.dot(values, values)
66

67 1
    def c11_dot(vect):
68 1
        return vector_dot_product(vect, vect)
69

70 1
    def c11_dot16(vect):
71 1
        return vector_dot_product16(vect, vect)
72

73 1
    def c11_dot16_nofcall(vect):
74 1
        return vector_dot_product16_nofcall(vect, vect)
75

76 1
    def c11_dot16_sse(vect):
77 1
        return vector_dot_product16_sse(vect, vect)
78

79 1
    return [simple_dot, c11_dot, c11_dot16, c11_dot16_nofcall, c11_dot16_sse]
80

81

82 1
def 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.
86

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
92

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:
96

97
    ::
98

99
        import mkl
100
        mkl.set_num_threads(1)
101

102
    .. index:: MKL_NUM_THREADS
103

104
    One example of use:
105

106
    .. runpython::
107
        :showcode:
108

109
        from cpyquickhelper.numbers import check_speed
110
        res = list(check_speed(dims=[100, 1000]))
111
        import pprint
112
        pprint.pprint(res)
113
    """
114 1
    import numpy  # pylint: disable=C0415
115 1
    fcts = _fcts()
116 1
    mx = max(dims)
117 1
    vect = numpy.ones((mx,))
118 1
    for i in range(0, vect.shape[0]):
119 1
        vect[i] = i
120 1
    for i in dims:
121 1
        values = vect[:i].copy()
122 1
        for fct in fcts:
123 1
            ct = {fct.__name__: fct}
124 1
            ct['values'] = values
125 1
            t = measure_time("{0}(values)".format(fct.__name__),
126
                             repeat=repeat, number=number, context=ct)
127 1
            t['name'] = fct.__name__
128 1
            if fLOG:
129 1
                fLOG(t)
130 1
            yield t

Read our documentation on viewing source code .

Loading