Python Numpy数组计算速度比等效Java代码慢
我试图用Python处理大型2D数组,但速度非常慢。例如: 开始=时间 结果=numpy.empty[50005000] 对于5000范围内的i: 对于5000范围内的j: 结果[i,j]=i*j%10 结束=时间 打印结束-开始8.8秒 Java中的相同程序要快得多: 长启动=System.currentTimeMillis; int[][]结果=新int[5000][5000]; 对于int i=0;i<5000;i++{ 对于int j=0;j<5000;j++{ 结果[i][j]=i*j%10; } } 长端=System.currentTimeMillis; System.out.printlend-开始;//121毫秒Python Numpy数组计算速度比等效Java代码慢,python,arrays,performance,numpy,Python,Arrays,Performance,Numpy,我试图用Python处理大型2D数组,但速度非常慢。例如: 开始=时间 结果=numpy.empty[50005000] 对于5000范围内的i: 对于5000范围内的j: 结果[i,j]=i*j%10 结束=时间 打印结束-开始8.8秒 Java中的相同程序要快得多: 长启动=System.currentTimeMillis; int[][]结果=新int[5000][5000]; 对于int i=0;i
这是因为Python是解释语言?有什么办法可以改进吗?或者为什么Python在处理矩阵、人工智能等方面如此流行?Python在AI方面非常流行,原因有很多: -易于原型化 -很多ML库/大commu -以CUDA为例,使用gpu对张量进行大规模并行计算 对于我们的问题,请尝试在python上使用本机列表如果您使用的是numpy,它可能会更重您实际上没有使用numpy的功能-您正在python级别手动执行循环。这大致相当于想知道,当你把车拖在身后时,如果步行到商店要花很长时间,为什么每个人都要用汽车 使用本机NumPy操作将您的工作推入C级循环。比如说,
temp = numpy.arange(5000)
result = numpy.outer(temp, temp) % 10
# or result = temp * temp[:, None] % 10
这会快得多。读到最后,看看NumPy的性能如何比Java代码高出5倍
numpy的优势在于。Python代码依赖于解释的循环,而解释的循环往往很慢
我将您的Python代码重写为矢量化计算,这立即将其速度提高了约16倍:
In [41]: v = np.arange(5000)
In [42]: %timeit np.outer(v, v) % 10
1 loop, best of 3: 544 ms per loop
就地计算%10而不是创建一个新阵列,可将速度再提高20%:
In [37]: def f(n):
...: v = np.arange(n)
...: a = np.outer(v, v)
...: a %= 10
...: return a
...:
In [39]: %timeit f(5000)
1 loop, best of 3: 437 ms per loop
编辑1:用32位而不是64位进行计算以匹配Java代码基本上与Java-h/t的性能相匹配,以@user2357112指出这一点:
In [50]: def f(n):
...: v = np.arange(n, dtype=np.int32)
...: a = np.outer(v, v)
...: a %= 10
...: return a
...:
In [51]: %timeit f(5000)
10 loops, best of 3: 126 ms per loop
编辑2:通过一点工作,我们可以使这段代码比您的Java实现快5倍
编辑3:请务必同时查看。有什么方法可以改进它吗
请参见时间性能差异:
In [13]: arr = np.empty([5000, 5000])
In [14]: %timeit np.multiply(*np.indices(arr.shape)) % 10
482 ms ± 2.73 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
其中表示网格的索引
为什么Python在处理矩阵、人工智能等方面如此流行
Numpy例程是用C语言实现的,C语言即使不是最快的语言,也是最快的语言之一,并且使用密集的数组。相关主题:
您还可以暗示,一个流行且功能强大的数据分析/数据科学库。由于其灵活的数据表示、简洁的语法、广泛的功能集和高效处理大型数据集,许多专家都首选和选择它。已经展示的@user2357112和@NPE示例的另一个选择是使用Jit编译器。纯解释的Python循环非常慢,应该避免在性能重要的地方使用 范例 时间安排
指定dtype='int32'并查看会发生什么-除非您在Windows上,否则您可能正在使用Java long的等效语言进行计算。这可能是造成时间差的另一个原因。@user2357112:你说得对,谢谢!让我更新答案。
In [13]: arr = np.empty([5000, 5000])
In [14]: %timeit np.multiply(*np.indices(arr.shape)) % 10
482 ms ± 2.73 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
import numpy as np
import numba as nb
import numexpr as ne
@nb.njit(parallel=True)
def func_1(num):
result = np.empty((num, num),dtype=np.int32)
for i in nb.prange(result.shape[0]):
for j in range(result.shape[1]):
result[i, j] = (i * j) % 10
return result
#The first call has a higher overhead due to compilation
#parallel: @nb.njit(parallel=True)
%timeit res=func_1(5000)
#20.7 ms ± 1.11 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
#single threaded: @nb.njit(parallel=True)
%timeit res=func_1(5000)
#71.9 ms ± 521 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)
#NPE
%%timeit
v = np.arange(5000, dtype=np.int32)
vt = v[np.newaxis].T
ne.evaluate('v * vt % 10')
#35.5 ms ± 863 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)