I have to use a lot of logarithmic calculations in one program. In terms of the logarithmic base, the procedure is not specific. I was wondering, if any base n
(2? 10? e?) is faster in the Python 3.5 math
module than others, because maybe under the hood all other bases a
are transformed into log_a(x) = log_n(x)/log_n(a)
. Or does the choice of the base not influence the speed of the calculation, because all bases are implemented in the same way using a C library?
In CPython, math.log
is base independent, but platform dependent. From the C source for the math
module, on lines 1940-1961, the code for math.log
is shown.
math_log_impl(PyObject *module, PyObject *x, int group_right_1,
PyObject *base)
/*[clinic end generated code: output=7b5a39e526b73fc9 input=0f62d5726cbfebbd]*/
{
PyObject *num, *den;
PyObject *ans;
num = loghelper(x, m_log, "log"); // uses stdlib log
if (num == NULL || base == NULL)
return num;
den = loghelper(base, m_log, "log"); // uses stdlib log
if (den == NULL) {
Py_DECREF(num);
return NULL;
}
ans = PyNumber_TrueDivide(num, den);
Py_DECREF(num);
Py_DECREF(den);
return ans;
}
This, no matter what, calculates the natural log of the number and base, so unless the C log
function has a special check for e
, it will run at the same speed.
This source also explains the other answer's log2
and log10
being faster than log
. They are implemented using the standard library log2
and log10
functions respectively, which will be faster. These functions, however, are defined differently depending on the platform.
Note: I am not very familiar with C so I may be wrong here.
Interesting question. I did some "good old" field test (CPython 3.6.2 on Linux, x86_64, i7-3740QM CPU - Python interpreter compiled with all optimizations available for this CPU turned ON).
>>> math.log10(3)
0.47712125471966244
>>> math.log(3, 10)
0.47712125471966244
>>> timeit.timeit('math.log(3, 10)', setup = 'import math')
0.2496643289923668
>>> timeit.timeit('math.log10(3)', setup = 'import math')
0.14756392200069968
Log10 is clearly faster than log(n, 10).
>>> math.log2(3.0)
1.584962500721156
>>> math.log(3.0, 2.0)
1.5849625007211563
>>> timeit.timeit('math.log2(3.0)', setup = 'import math')
0.16744944200036116
>>> timeit.timeit('math.log(3.0, 2.0)', setup = 'import math')
0.22228705599263776
Log2 is also clearly faster than log(n, 2). Btw, either way, floats and ints are equally fast.
With numpy
, the picture is different. It kind of does not matter what you do:
>>> timeit.timeit('numpy.log(numpy.arange(1, 10))', setup = 'import numpy')
2.725074506000965
>>> timeit.timeit('numpy.log10(numpy.arange(1, 10))', setup = 'import numpy')
2.613872367001022
>>> timeit.timeit('numpy.log2(numpy.arange(1, 10))', setup = 'import numpy')
2.58251854799164
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With