Python using NaN or None as sentinel
Comparing to None
instead of NaN
is:
- 4..50 times faster in CPython
- more than 1000 times faster in PyPy3 with Numpy, same speed with
math
Benchmarks using Intel Coffee Lake CPU with:
ipython
Python 3.7.3 IPython 7.7.0 Numpy 1.16.4
pypy3 -m IPython
Python 3.6.1 (PyPy3 7.1.1)
Numpy is well known to be slower at scalar operations than pure Python. But many data science and STEM application using arrays are vastly faster and more convenient with Numpy than pure Python methods.
from numpy import isnan
%timeit isnan(0.)
- CPython: 428 ns ± 1.74 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)
Python NaN
from math import isnan
%timeit isnan(0.)
- CPython: 45.7 ns ± 0.209 ns per loop (mean ± std. dev. of 7 runs, 10000000 loops each)
- PyPy3: 0.988 ns ± 0.00506 ns per loop (mean ± std. dev. of 7 runs, 1000000000 loops each)
Python None
%timeit 0. is not None
- CPython: 17 ns ± 0.328 ns per loop (mean ± std. dev. of 7 runs, 100000000 loops each)
- PyPy3: 0.987 ns ± 0.0041 ns per loop (mean ± std. dev. of 7 runs, 1000000000 loops each)
Numba
using python-performance
python NoneVsNan.py
--> Numba NaN sentinel: 1.00e-07
--> Numba None sentinel: 1.00e-07
--> CPython NaN sentinel: 2.00e-07
--> Numpy NaN sentinel: 6.00e-07
--> CPython None sentinel: 1.00e-07