首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >numpy数组上的余数函数(%)运行时间远远长于手动计算余数

numpy数组上的余数函数(%)运行时间远远长于手动计算余数
EN

Stack Overflow用户
提问于 2018-09-09 16:47:21
回答 1查看 1.5K关注 0票数 32

在过去的几天里,我一直在致力于改进python函数的运行时,这需要多次使用余数函数(%)以及其他一些东西。我的主要测试用例是超过80,000个元素的numpy数组(单调增加),有10000次迭代,尽管我也尝试过各种不同大小的数组。

最终,我达到了余数函数成为主要瓶颈的地步,并尝试了各种解决方案。这是我在运行以下代码时发现的行为:

代码语言:javascript
运行
复制
import numpy as np
import time

a = np.random.rand(80000)
a = np.cumsum(a)
d = 3
start_time1 = time.time()
for i in range(10000):
    b = a % d
    d += 0.001
end_time1 = time.time()
d = 3
start_time2 = time.time()
for i in range(10000):
    b = a - (d * np.floor(a / d))
    d += 0.001
end_time2 = time.time()
print((end_time1 - start_time1) / 10000)
print((end_time2 - start_time2) / 10000)

输出为:

代码语言:javascript
运行
复制
0.0031344462633132934
0.00022937238216400147

将数组大小增加到800,000时:

代码语言:javascript
运行
复制
0.014903099656105041
0.010498356819152833

(对于这篇文章,我只运行了一次代码作为实际输出,同时试图理解问题,我得到了一致的结果。)

虽然这解决了我的运行时问题--我很难理解为什么。我是不是遗漏了什么?我能想到的唯一区别是额外的函数调用的开销,但第一种情况相当极端(1.5倍的运行时也不够好),如果是这种情况,我会认为np.remainder函数的存在是没有意义的。

编辑:我尝试用非numpy循环测试相同的代码:

代码语言:javascript
运行
复制
import numpy as np
import time


def pythonic_remainder(array, d):
    b = np.zeros(len(array))
    for i in range(len(array)):
        b[i] = array[i] % d

def split_pythonic_remainder(array, d):
    b = np.zeros(len(array))
    for i in range(len(array)):
        b[i] = array[i] - (d * np.floor(array[i] / d))

def split_remainder(a, d):
    return a - (d * np.floor(a / d))

def divide(array, iterations, action):
    d = 3
    for i in range(iterations):
        b = action(array, d)
        d += 0.001

a = np.random.rand(80000)
a = np.cumsum(a)
start_time = time.time()
divide(a, 10000, split_remainder)
print((time.time() - start_time) / 10000)

start_time = time.time()
divide(a, 10000, np.remainder)
print((time.time() - start_time) / 10000)
start_time = time.time()
divide(a, 10000, pythonic_remainder)
print((time.time() - start_time) / 10000)

start_time = time.time()
divide(a, 10000, split_pythonic_remainder)
print((time.time() - start_time) / 10000)

我得到的结果是:

代码语言:javascript
运行
复制
0.0003770533800125122
0.003932329940795899
0.018835473942756652
0.10940513386726379

我发现有趣的是,在非麻木的情况下,情况正好相反。

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

https://stackoverflow.com/questions/52242832

复制
相关文章

相似问题

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