Following code can speedup 4x on my PC, it's faster because:
- use
ndarray.item()
to get values from array. - use set object to save unprocessed index.
- don't create
numpy.arange()
in the while loop.
Python code:
def dijkway2(dijkpredmat, i, j):
wayarr = []
while (i != j) & (j >= 0):
wayarr.append(j)
j = dijkpredmat.item(i,j)
return wayarr
def jumpvec2(pmat,node):
jumps = np.zeros(len(pmat))
jumps[node] = -999
todo = set()
for i in range(len(pmat)):
if i != node:
todo.add(i)
indexs = np.arange(len(pmat), 0, -1)
while todo:
r = todo.pop()
dway = dijkway2(pmat, node, r)
jumps[dway] = indexs[-len(dway):]
todo -= set(dway)
return jumps
To speedup even more, you can use cython:
import numpy as np
cimport numpy as np
import cython
@cython.wraparound(False)
@cython.boundscheck(False)
cpdef dijkway3(int[:, ::1] m, int i, int j):
cdef list wayarr = []
while (i != j) & (j >= 0):
wayarr.append(j)
j = m[i,j]
return wayarr
@cython.wraparound(False)
@cython.boundscheck(False)
def jumpvec3(int[:, ::1] pmat, int node):
cdef np.ndarray jumps
cdef int[::1] jumps_buf
cdef int i, j, r, n
cdef list dway
jumps = np.zeros(len(pmat), int)
jumps_buf = jumps
jumps[node] = -999
for i in range(len(jumps)):
if jumps_buf[i] != 0:
continue
r = i
dway = dijkway3(pmat, node, r)
n = len(dway)
for j in range(n):
jumps_buf[<int>dway[j]] = n - j
return jumps
Here is my test, the cython version is 80x faster:
%timeit jumpvec3(pmat,1)
%timeit jumpvec2(pmat, 1)
%timeit jumpvec(pmat, 1)
output:
1000 loops, best of 3: 138 µs per loop
100 loops, best of 3: 2.81 ms per loop
100 loops, best of 3: 10.8 ms per loop