In [1]:
import hope
hope.config.optimize = True
hope.config.verbose = True
hope.config.keeptemp = True
import numba
import numpy as np
import numexpr as ne

from util import perf_comp_data
from native_util import load
%load_ext cythonmagic
%load_ext version_information
%version_information numpy, Cython, numba, hope, numexpr


Out[1]:
SoftwareVersion
Python2.7.8 (default, Jul 13 2014, 17:11:32) [GCC 4.2.1 Compatible Apple LLVM 5.1 (clang-503.0.40)]
IPython1.1.0
OSposix [darwin]
numpy1.8.1
Cython0.20.2
numba0.13.3
hope0.3.0
numexpr2.4
Thu Sep 04 15:13:34 2014 CEST

In [2]:
# Python version

def ln_python(X, Y):
    Y[:] = (X-1) - (X-1)**2 / 2 + (X-1)**3 / 3 - (X-1)**4 / 4 + (X-1)**5 / 5 - (X-1)**6 / 6 + (X-1)**7 / 7 - (X-1)**8 / 8 + (X-1)**9 / 9

In [3]:
# Python version

def ln_python_exp(X, Y):
    x = (X - 1)
    x2 = x*x
    x4 = x2*x2
    x6 = x4*x2
    x8 = x4*x4
    Y[:] = x - x2 / 2 + x * x2 / 3 - x4 / 4 + x * x4 / 5 - x6 / 6 + x6 * x / 7 - x8 / 8 + x8 * x / 9

In [4]:
# NumExpr version
def ln_numexpr(X, Y):
    Y[:] = ne.evaluate("(X-1) - (X-1)**2 / 2 + (X-1)**3 / 3 - (X-1)**4 / 4 + (X-1)**5 / 5 - (X-1)**6 / 6 + (X-1)**7 / 7 - (X-1)**8 / 8 + (X-1)**9 / 9")

In [5]:
# Hope version
@hope.jit
def ln_hope(X, Y):
    Y[:] = (X-1) - (X-1)**2 / 2 + (X-1)**3 / 3 - (X-1)**4 / 4 + (X-1)**5 / 5 - (X-1)**6 / 6 + (X-1)**7 / 7 - (X-1)**8 / 8 + (X-1)**9 / 9


/Users/jakeret/workspace/hope/hope/jit.py:128: UserWarning: Recompiling... Reason: State is inconsistent with config. Inconsistent state key: [optimize].
  warnings.warn("Recompiling... Reason: {0}".format(le))

In [6]:
# Hope version

import hope
hope.config.optimize = False
@hope.jit
def ln_hope_exp(X, Y):
    x = (X - 1)
    x2 = x*x
    x4 = x2*x2
    x6 = x4*x2
    x8 = x4*x4
    Y[:] = x - x2 / 2 + x * x2 / 3 - x4 / 4 + x * x4 / 5 - x6 / 6 + x6 * x / 7 - x8 / 8 + x8 * x / 9

In [7]:
# numba version

@numba.jit
def ln_numba(X, Y):
    Y[:] = (X-1) - (X-1)**2 / 2 + (X-1)**3 / 3 - (X-1)**4 / 4 + (X-1)**5 / 5 - (X-1)**6 / 6 + (X-1)**7 / 7 - (X-1)**8 / 8 + (X-1)**9 / 9

In [8]:
# numba version

import numba

@numba.jit
def ln_numba_exp(X, Y):
    x = (X - 1)
    x2 = x*x
    x4 = x2*x2
    x6 = x4*x2
    x8 = x4*x4
    Y[:] = x - x2 / 2 + x * x2 / 3 - x4 / 4 + x * x4 / 5 - x6 / 6 + x6 * x / 7 - x8 / 8 + x8 * x / 9

In [9]:
%load_ext cythonmagic


The cythonmagic extension is already loaded. To reload it, use:
  %reload_ext cythonmagic

In [10]:
%%cython

cimport cython

cimport cython
import numpy as np
cimport numpy as np

@cython.boundscheck(False)
@cython.wraparound(False)
def ln_cython(np.ndarray[np.double_t, ndim=1] X, np.ndarray[np.double_t, ndim=1] Y):
    Y[:] = (X-1) - (X-1)**2 / 2 + (X-1)**3 / 3 - (X-1)**4 / 4 + (X-1)**5 / 5 - (X-1)**6 / 6 + (X-1)**7 / 7 - (X-1)**8 / 8 + (X-1)**9 / 9

    
@cython.boundscheck(False)
@cython.wraparound(False)
def ln_cython_exp(np.ndarray[np.float_t, ndim=1] X, np.ndarray[np.float_t, ndim=1] Y):
    cdef np.ndarray[np.double_t, ndim=1] x = (X - 1)
    cdef np.ndarray[np.double_t, ndim=1] x2 = x*x
    cdef np.ndarray[np.double_t, ndim=1] x4 = x2*x2
    cdef np.ndarray[np.double_t, ndim=1] x6 = x4*x2
    cdef np.ndarray[np.double_t, ndim=1] x8 = x4*x4
    Y[:] = x - x2 / 2 + x * x2 / 3 - x4 / 4 + x * x4 / 5 - x6 / 6 + x6 * x / 7 - x8 / 8 + x8 * x / 9

In [11]:
from native_util import load
native_ln_mod = load("ln")
ln_native = native_ln_mod.run

native_ln_opt_mod = load("ln_opt")
ln_native_opt = native_ln_opt_mod.run

native_ln_exp_mod = load("ln_exp")
ln_native_exp = native_ln_exp_mod.run


running build_ext
building 'ln' extension
C compiler: /usr/bin/clang -fno-strict-aliasing -fno-common -dynamic -pipe -Os -fwrapv -DNDEBUG -g -fwrapv -O3 -Wall -Wstrict-prototypes

compile options: '-I/Users/jakeret/Library/Python/2.7/lib/python/site-packages/numpy/core/include -I/opt/local/Library/Frameworks/Python.framework/Versions/2.7/include/python2.7 -c'
extra options: '-Wall -Wno-unused-variable -march=native -stdlib=libc++ -std=c++11'
clang: ././src/ln.cpp
/usr/bin/clang++ -bundle -undefined dynamic_lookup -L/opt/local/lib -Wl,-headerpad_max_install_names -L/opt/local/lib/db46 ./src/ln.o -o ./ln.so

running build_ext
building 'ln_opt' extension
C compiler: /usr/bin/clang -fno-strict-aliasing -fno-common -dynamic -pipe -Os -fwrapv -DNDEBUG -g -fwrapv -O3 -Wall -Wstrict-prototypes

compile options: '-I/Users/jakeret/Library/Python/2.7/lib/python/site-packages/numpy/core/include -I/opt/local/Library/Frameworks/Python.framework/Versions/2.7/include/python2.7 -c'
extra options: '-Wall -Wno-unused-variable -march=native -stdlib=libc++ -std=c++11'
clang: ././src/ln_opt.cpp
/usr/bin/clang++ -bundle -undefined dynamic_lookup -L/opt/local/lib -Wl,-headerpad_max_install_names -L/opt/local/lib/db46 ./src/ln_opt.o -o ./ln_opt.so

running build_ext
building 'ln_exp' extension
C compiler: /usr/bin/clang -fno-strict-aliasing -fno-common -dynamic -pipe -Os -fwrapv -DNDEBUG -g -fwrapv -O3 -Wall -Wstrict-prototypes

compile options: '-I/Users/jakeret/Library/Python/2.7/lib/python/site-packages/numpy/core/include -I/opt/local/Library/Frameworks/Python.framework/Versions/2.7/include/python2.7 -c'
extra options: '-Wall -Wno-unused-variable -march=native -stdlib=libc++ -std=c++11'
clang: ././src/ln_exp.cpp
/usr/bin/clang++ -bundle -undefined dynamic_lookup -L/opt/local/lib -Wl,-headerpad_max_install_names -L/opt/local/lib/db46 ./src/ln_exp.o -o ./ln_exp.so


In [13]:
# Hope version - optimized

import hope
hope.config.optimize = True

@hope.jit
def ln_hope_opt(X, Y):
    Y[:] = (X-1) - (X-1)**2 / 2 + (X-1)**3 / 3 - (X-1)**4 / 4 + (X-1)**5 / 5 - (X-1)**6 / 6 + (X-1)**7 / 7 - (X-1)**8 / 8 + (X-1)**9 / 9


hope.config.optimize = False

In [15]:
import numpy as np

X = np.random.random(10000).astype(np.float64)
Y = np.ones_like(X)

In [17]:
Y1 = np.ones_like(X)
Y2 = np.ones_like(X)
Y3 = np.ones_like(X)
Y4 = np.ones_like(X)
Y5 = np.ones_like(X)
Y6 = np.ones_like(X)
Y7 = np.ones_like(X)
Y8 = np.ones_like(X)
Y9 = np.ones_like(X)
Y10 = np.ones_like(X)
Y11 = np.ones_like(X)
Y12 = np.ones_like(X)
Y13 = np.ones_like(X)

ln_python(X, Y1)
ln_python_exp(X, Y2)
ln_cython(X, Y3)
ln_cython_exp(X, Y4)
ln_numexpr(X, Y5)
ln_hope(X, Y6)
ln_hope_exp(X, Y7)
ln_numba(X, Y8)
ln_numba_exp(X, Y9)
ln_native(X, Y10)
ln_native_opt(X, Y11)
ln_native_exp(X, Y12)
ln_hope_opt(X, Y13)

assert np.allclose(Y1,Y2, 1E-10)
assert np.allclose(Y1,Y3, 1E-10)
assert np.allclose(Y1,Y4, 1E-10)
assert np.allclose(Y1,Y5, 1E-10)
assert np.allclose(Y1,Y6, 1E-10)
assert np.allclose(Y1,Y7, 1E-10)
assert np.allclose(Y1,Y8, 1E-10)
assert np.allclose(Y1,Y9, 1E-10)
assert np.allclose(Y1,Y10, 1E-10)
assert np.allclose(Y1,Y11, 1E-10)
assert np.allclose(Y1,Y12, 1E-10)
assert np.allclose(Y1,Y13, 1E-10)

In [18]:
import numexpr as ne

print "python"
%timeit ln_python(X, Y)
%timeit ln_python_exp(X, Y)
print "numexpr (1)"
ne.set_num_threads(1)
%timeit ln_numexpr(X, Y)
print "numexpr ({0})".format(ne.detect_number_of_cores())
ne.set_num_threads(ne.detect_number_of_cores())
%timeit ln_numexpr(X, Y)
print "hope"
%timeit ln_hope(X, Y)
%timeit ln_hope_exp(X, Y)
%timeit ln_hope_opt(X, Y)
print "cython"
%timeit ln_cython(X, Y)
%timeit ln_cython_exp(X, Y)
print "numba"
%timeit ln_numba(X, Y)
%timeit ln_numba_exp(X, Y)
print "native"
%timeit ln_native(X, Y)
%timeit ln_native_opt(X, Y)
%timeit ln_native_exp(X, Y)


python
100 loops, best of 3: 2.4 ms per loop
1000 loops, best of 3: 299 µs per loop
numexpr (1)
1000 loops, best of 3: 400 µs per loop
numexpr (8)
1000 loops, best of 3: 200 µs per loop
hope
10000 loops, best of 3: 128 µs per loop
1000 loops, best of 3: 212 µs per loop
10000 loops, best of 3: 128 µs per loop
cython
100 loops, best of 3: 2.4 ms per loop
1000 loops, best of 3: 305 µs per loop
numba
100 loops, best of 3: 2.41 ms per loop
1000 loops, best of 3: 305 µs per loop
native
100 loops, best of 3: 2.12 ms per loop
10000 loops, best of 3: 128 µs per loop
10000 loops, best of 3: 106 µs per loop

In [19]:
from util import perf_comp_data

In [20]:
func_list = ["ln_python", "ln_python_exp", 
             "ln_numexpr", 
             "ln_hope", "ln_hope_exp", "ln_hope_opt", 
             "ln_cython", "ln_cython_exp", 
             "ln_numba", "ln_numba_exp", 
             "ln_native", "ln_native_opt", "ln_native_exp", ]
perf_comp_data(func_list,
               len(func_list)*["X, Y"], rep=100)


function: ln_native_exp       , av. time sec:   0.00010705, min. time sec:   0.00010586, relative:       1.0
function: ln_hope_opt         , av. time sec:   0.00012398, min. time sec:   0.00012398, relative:       1.2
function: ln_hope             , av. time sec:   0.00012422, min. time sec:   0.00012398, relative:       1.2
function: ln_native_opt       , av. time sec:   0.00012803, min. time sec:   0.00012708, relative:       1.2
function: ln_hope_exp         , av. time sec:   0.00020707, min. time sec:   0.00020695, relative:       1.9
function: ln_numexpr          , av. time sec:   0.00021243, min. time sec:   0.00018501, relative:       2.0
function: ln_python_exp       , av. time sec:   0.00029302, min. time sec:   0.00029206, relative:       2.7
function: ln_numba_exp        , av. time sec:   0.00030351, min. time sec:   0.00029993, relative:       2.8
function: ln_cython_exp       , av. time sec:   0.00030696, min. time sec:   0.00029683, relative:       2.9
function: ln_native           , av. time sec:   0.00215054, min. time sec:   0.00208783, relative:      20.1
function: ln_cython           , av. time sec:   0.00241804, min. time sec:   0.00235510, relative:      22.6
function: ln_numba            , av. time sec:   0.00241804, min. time sec:   0.00237322, relative:      22.6
function: ln_python           , av. time sec:   0.00243747, min. time sec:   0.00235200, relative:      22.8

In [ ]: