是否有任何理由为什么以下代码在2s运行,
def euclidean_distance_square(x1, x2):
return -2*np.dot(x1, x2.T) + np.expand_dims(np.sum(np.square(x1), axis=1), axis=1) + np.sum(np.square(x2), axis=1)
Run Code Online (Sandbox Code Playgroud)
而以下numba代码在12s运行?
@jit(nopython=True)
def euclidean_distance_square(x1, x2):
return -2*np.dot(x1, x2.T) + np.expand_dims(np.sum(np.square(x1), axis=1), axis=1) + np.sum(np.square(x2), axis=1)
Run Code Online (Sandbox Code Playgroud)
我的x1是尺寸矩阵(1,512),x2是尺寸矩阵(3000000,512).Numba可以慢得多,这很奇怪.我用错了吗?
我真的需要加快速度,因为我需要运行这个功能300万次而且2s仍然太慢了.
我需要在CPU上运行它,因为你可以看到x2的维度是如此巨大,它无法加载到GPU(或至少我的GPU),没有足够的内存.
我注意到,非常紧张,np.sum比手写总和慢10倍.
带轴的np.sum:
p1 = np.random.rand(10000, 2)
def test(p1):
return p1.sum(axis=1)
%timeit test(p1)
Run Code Online (Sandbox Code Playgroud)
每回路186μs±4.21μs(平均值±标准偏差,7次运行,每次1000次循环)
没有轴的np.sum:
p1 = np.random.rand(10000, 2)
def test(p1):
return p1.sum()
%timeit test(p1)
Run Code Online (Sandbox Code Playgroud)
每回路17.9μs±236 ns(平均值±标准偏差,7次运行,每次10000次循环)
+:
p1 = np.random.rand(10000, 2)
def test(p1):
return p1[:,0] + p1[:,1]
%timeit test(p1)
Run Code Online (Sandbox Code Playgroud)
每个环路15.8μs±328 ns(平均值±标准偏差,7次运行,每次100000次循环)
乘法:
p1 = np.random.rand(10000, 2)
def test(p1):
return p1[:,0]*p1[:,1]
%timeit test(p1)
Run Code Online (Sandbox Code Playgroud)
每个环路15.7μs±701 ns(平均值±标准偏差,7次运行,每次10000次循环)
我没有看到任何理由.知道为什么吗?我的numpy版本是1.15.3.
编辑:10000000:
np.sum (with axis): 202 ms (5 x)
np.sum (without axis): 12 ms
+ : 46 ms (1 x)
* : 44.3 ms …Run Code Online (Sandbox Code Playgroud) 我需要概述一下在高性能数字代码中使用Cython可以获得的性能.我感兴趣的一件事是找出优化的C编译器是否可以对Cython生成的代码进行矢量化.所以我决定编写以下小例子:
import numpy as np
cimport numpy as np
cimport cython
@cython.boundscheck(False)
@cython.wraparound(False)
cpdef int f(np.ndarray[int, ndim = 1] f):
cdef int array_length = f.shape[0]
cdef int sum = 0
cdef int k
for k in range(array_length):
sum += f[k]
return sum
Run Code Online (Sandbox Code Playgroud)
我知道有Numpy函数可以完成这项工作,但我希望有一个简单的代码,以便了解Cython的可能性.事实证明,生成的代码:
from distutils.core import setup
from Cython.Build import cythonize
setup(ext_modules = cythonize("sum.pyx"))
Run Code Online (Sandbox Code Playgroud)
并呼吁:
python setup.py build_ext --inplace
Run Code Online (Sandbox Code Playgroud)
为循环生成一个看起来像这样的C代码:
for (__pyx_t_2 = 0; __pyx_t_2 < __pyx_t_1; __pyx_t_2 += 1) {
__pyx_v_sum = __pyx_v_sum + (*(int *)((char *)
__pyx_pybuffernd_f.rcbuffer->pybuffer.buf + …Run Code Online (Sandbox Code Playgroud) 我对 Numba 的工作有点陌生,但我已经了解了它的要点。我想知道是否有更高级的技巧可以使四个嵌套for循环比我现在的速度更快。特别是,我需要计算以下积分:
其中B是二维数组,S0和E是某些参数。我的代码如下:
import numpy as np
from numba import njit, double
def calc_gb_gauss_2d(b,s0,e,dx):
n,m=b.shape
norm = 1.0/(2*np.pi*s0**2)
gb = np.zeros((n,m))
for i in range(n):
for j in range(m):
for ii in range(n):
for jj in range(m):
gb[i,j]+=np.exp(-(((i-ii)*dx)**2+((j-jj)*dx)**2)/(2.0*(s0*(1.0+e*b[i,j]))**2))
gb[i,j]*=norm
return gb
calc_gb_gauss_2d_nb = njit(double[:, :](double[:, :],double,double,double))(calc_gb_gauss_2d)
Run Code Online (Sandbox Code Playgroud)
对于大小为输入的数组,256x256计算速度为:
In [4]: a=random.random((256,256))
In [5]: %timeit calc_gb_gauss_2d_nb(a,0.1,1.0,0.5)
The slowest run took 8.46 times longer than the fastest. This could mean that an intermediate result is being cached.
1 …Run Code Online (Sandbox Code Playgroud)