Created
April 1, 2015 12:37
-
-
Save ufechner7/95db14f734edd51dcd9b to your computer and use it in GitHub Desktop.
Comparing the speed of accessing record arrays and two dimensional arrays using numba
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# -*- coding: utf-8 -*- | |
""" Accessing record arrays with numba 0.17 is 10 times slower than using two dimensional arrays. """ | |
from numba import jit | |
import numpy as np | |
import time | |
V_WIND = 8.0 | |
V_wind = 0 # (westwind, downwind direction to the east) | |
V_wind_gnd = 1 | |
Result = 2 | |
class Timer(object): | |
def __init__(self, verbose=False): | |
self.verbose = verbose | |
def __enter__(self): | |
self.start = time.time() | |
return self | |
def __exit__(self, *args): | |
self.end = time.time() | |
self.secs = self.end - self.start | |
self.msecs = self.secs * 1000 # millisecs | |
if self.verbose: | |
print 'elapsed time: %f ms' % self.msecs | |
V_WIND = 8.0 | |
def form(number): | |
""" print a number with two decimal digits """ | |
return "{:5.2f}".format(number) | |
@jit(nopython = False) | |
def sub(a, b, result): | |
""" Calculate the difference of two 3d vectors. """ | |
result[0] = a[0] - b[0] | |
result[1] = a[1] - b[1] | |
result[2] = a[2] - b[2] | |
def getRecArray(): | |
x_dt = np.dtype([('v_wind', np.float64), | |
('v_wind_gnd', np.float64), | |
('result', np.float64)]) | |
buf = np.zeros((3, 3)) # initialize the record array with zeros | |
vec3 = np.recarray(3, dtype=x_dt, buf=buf) | |
vec3.v_wind[0] = 1.5 * V_WIND # (westwind, downwind direction to the east at 200m height) | |
vec3.v_wind_gnd[0] = V_WIND # (westwind, downwind direction to the east) | |
return vec3 | |
@jit(nopython=True) | |
def sub_plain(a, b, result): | |
sub(a, b, result) | |
@jit(nopython=True) | |
def sub_array(vec3): | |
sub(vec3[V_wind], vec3[V_wind_gnd], vec3[Result]) | |
@jit(nopython=False) | |
def sub_rec_array(vec3): | |
sub(vec3.v_wind, vec3.v_wind_gnd, vec3.result) | |
def getVec3(): | |
vec3 = np.zeros((3, 3)) | |
vec3[V_wind, 0] = 1.5 * V_WIND # (westwind, downwind direction to the east at 200m height) | |
vec3[V_wind_gnd, 0] = V_WIND # (westwind, downwind direction to the east) | |
return vec3 | |
def init(): | |
rec3 = getRecArray() | |
print rec3.v_wind | |
print rec3.v_wind_gnd | |
sub_rec_array(rec3) | |
sub_plain(rec3.v_wind, rec3.v_wind_gnd, rec3.result) | |
print rec3.result | |
vec3 = getVec3() | |
sub_array(vec3) | |
return rec3 | |
rec3 = init() | |
vec3 = getVec3() | |
if __name__ == "__main__": | |
with Timer() as t0: | |
for i in range(10000): | |
pass | |
print "time for empty loop ", t0.secs | |
a = rec3.v_wind | |
b = rec3.v_wind_gnd | |
result = rec3. result | |
with Timer() as t1: | |
for i in range(10000): | |
sub_plain(a, b, result) | |
print "time for numba sub_plain [µs]: ", form((t1.secs-t0.secs) / 10000 * 1e6) | |
with Timer() as t1: | |
for i in range(10000): | |
sub_rec_array(rec3) | |
print "time for numba sub_rec_array [µs]: ", form((t1.secs-t0.secs) / 10000 * 1e6) | |
with Timer() as t1: | |
for i in range(10000): | |
sub_array(vec3) | |
print "time for numba sub_array [µs]: ", form((t1.secs-t0.secs) / 10000 * 1e6) | |
""" | |
In [6]: runfile('/home/ufechner/00PythonSoftware/KiteSim/numba/bench_rec_array.py', wdir='/home/ufechner/00PythonSoftware/KiteSim/numba') | |
[ 12. 0. 0.] | |
[ 8. 0. 0.] | |
[ 4. 0. 0.] | |
time for empty loop 0.000369071960449 | |
time for numba sub_plain [µs]: 0.33 | |
time for numba sub_rec_array [µs]: 1.97 | |
time for numba sub_array [µs]: 0.19 | |
In [7]: | |
""" |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment