Mic*_*hal 0 python arrays performance numpy
我正在尝试使用Python处理大型2D数组,但速度非常慢。例如:
start = time.time()
result = numpy.empty([5000, 5000])
for i in range(5000):
for j in range(5000):
result[i, j] = (i * j) % 10
end = time.time()
print(end - start) # 8.8 s
Run Code Online (Sandbox Code Playgroud)
Java中的相同程序要快得多:
long start = System.currentTimeMillis();
int[][] result = new int[5000][5000];
for (int i = 0; i < 5000; i++) {
for (int j = 0; j < 5000; j++) {
result[i][j] = (i * j) % 10;
}
}
long end = System.currentTimeMillis();
System.out.println(end - start); // 121 ms
Run Code Online (Sandbox Code Playgroud)
这是因为Python是解释语言吗?有什么办法可以改善吗?还是为什么Python在处理矩阵,人工智能等方面如此受欢迎?
您实际上并没有使用 NumPy的功能-您是在Python级别手动执行循环。这大致类似于想知道为什么当您将汽车拖到自己身后时,如果花这么长时间才能步行到商店,那么每个人都使用汽车。
使用本机NumPy操作将您的工作推入C级循环。例如,
temp = numpy.arange(5000)
result = numpy.outer(temp, temp) % 10
# or result = temp * temp[:, None] % 10
Run Code Online (Sandbox Code Playgroud)
这样会更快。
阅读最后,了解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
Run Code Online (Sandbox Code Playgroud)
% 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
Run Code Online (Sandbox Code Playgroud)
编辑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
Run Code Online (Sandbox Code Playgroud)
编辑2:通过一点点工作,我们可以使这段代码比Java实现快5倍左右(此处ne指的是numexpr模块):
In [69]: v = np.arange(5000, dtype=np.int32)
In [70]: vt = v[np.newaxis].T
In [71]: %timeit ne.evaluate('v * vt % 10')
10 loops, best of 3: 25.3 ms per loop
Run Code Online (Sandbox Code Playgroud)
编辑3:请确保还看看@ max9111给出的答案。
| 归档时间: |
|
| 查看次数: |
146 次 |
| 最近记录: |