首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >使用numpy min、max (或numba)进行Python优化

使用numpy min、max (或numba)进行Python优化
EN

Stack Overflow用户
提问于 2018-07-25 23:47:19
回答 2查看 1.8K关注 0票数 0

我非常需要用python,numpy来优化性能。

我的数据是这样的,

代码语言:javascript
复制
a1 = np.array(np.random.random(500000) * 1000)
a2 = np.array(np.random.random(500000) * 5000)

使用不同的ndarray a1,a2,我想计算最小-最大间隙。

numpy:

代码语言:javascript
复制
np.max(a1) - np.min(a2)

numba:

代码语言:javascript
复制
@nb.jit(nb.float64(nb.float64, nb.float64), cache=True, fastmath=True)
def nb_max_min(s1, s2):
    return np.max(s1) - np.min(s2)

但是,我得到了令人失望的结果

代码语言:javascript
复制
min-max(numba): 1.574092000000249 ms
max-max(numpy): 1.4246419999999205 ms

如果可能的话,我想在~0.xx毫秒内进行更快的计算。如何克服这种优化?

更新

我只测量了max - min部分。我的计时代码在这里。

代码语言:javascript
复制
import time


def timing(label, fn):
    t0 = time.perf_counter()
    fn()
    t1 = time.perf_counter()
    print('{}: {} ms'.format(label, (t1 - t0) * 1000))

我所有的代码都在这里

代码语言:javascript
复制
@nb.jit(nb.float64(nb.float64, nb.float64), cache=True, fastmath=True)
def nb_max_min(s1, s2):
    return np.max(s1) - np.min(s2)


a1 = np.random.random(periods) * 2000
a2 = np.random.random(periods) * 1000
timing('nb_min_max', lambda: nb_max_min(a1, a2))
timing('nb_min_max', lambda: nb_max_min(a1, a2))
timing('nb_min_max', lambda: nb_max_min(a1, a2))
timing('max-max', lambda: np.max(a1) - np.min(a2))
timing('max-max', lambda: np.max(a1) - np.min(a2))
timing('max-max', lambda: np.max(a1) - np.min(a2))

这就是结果

代码语言:javascript
复制
nb_min_max: 0.728947999999896 ms
nb_min_max: 1.0030130000000526 ms
nb_min_max: 1.3124690000001493 ms
max-max: 1.662436000000156 ms
max-max: 0.9315169999997153 ms
max-max: 1.9570019999992638 ms

我也尝试过timeit

代码语言:javascript
复制
%timeit np.max(a1) - np.min(a2)

475 µs ± 9.72 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)

我认为这是使用python最快的方法。Numpy或numba的结果没有显著差异。正如user2699评论的那样,fortran是优化的最后机会。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2018-07-26 05:38:41

你是如何获得这些非常慢的计时的?

代码

代码语言:javascript
复制
import numba as nb
import numpy as np
import time

a1 = np.array(np.random.random(500000) * 1000)
a2 = np.array(np.random.random(500000) * 5000)

@nb.jit(nb.float64(nb.float64[:], nb.float64[:]),parallel=True,fastmath=True)
def nb_max_min(s1, s2):
    return np.max(s1) - np.min(s2)

def np_max_min(s1,s2):
  return np.max(s1) - np.min(s2)

t1=time.time()
for i in range(10000):
  res_1=np_max_min(a1, a2)

print(str((time.time()-t1)/10)+ ' ms')

t1=time.time()
for i in range(10000):
  res_2=nb_max_min(a1, a2)

print(str((time.time()-t1)/10)+ ' ms')
np.allclose(res_1,res_2)

结果

代码语言:javascript
复制
Numpy: 0.298ms (=26.8 GB/s)
Numba: 0.243ms (=33 GB/s)

讨论

这些简单的操作是内存有限的。最大值。我的酷睿i7第四代的内存吞吐量是25,6 L3/s。Numba甚至大大超过了内存带宽,因为缓存效应(问题或多或少适合于L3缓存)实际代码中的.The计时可能会更低,因为输入数组可能还没有在L3缓存中。

票数 1
EN

Stack Overflow用户

发布于 2018-07-26 00:53:25

在ipython中使用'%timeit‘魔术,我得到了以下结果:

数组生成:

代码语言:javascript
复制
%%timeit
a1 = np.array(np.random.random(500000) * 1000)
a2 = np.array(np.random.random(500000) * 5000)
% 23.3 ms

最小-最大间隙:

代码语言:javascript
复制
%%timeit
np.max(a1) - np.min(a2)
% 444 µs

我认为这已经很快了,也许你测量了一些额外的开销,就像@juvian建议的那样?

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/51523034

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档