首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >很长的循环剩余时间

很长的循环剩余时间
EN

Stack Overflow用户
提问于 2022-02-12 22:33:33
回答 1查看 57关注 0票数 2

我试图将MATLAB脚本的数值输出与numpy的输出进行比较。

作业作业中的任务是将10^-N的值添加到自己10^N乘以

目的是要证明计算机在这样的计算中有其局限性。结果应该是1,但随着N的增加,误差也会增加。对于这个问题,N应该是0,1,2,.,8.

我的MATLAB脚本运行很快,没有问题:

代码语言:javascript
运行
复制
solns = zeros(1, 9);

for N = 0:8
    for ii = 1:(10^N)
        solns(N+1) = solns(N+1) + 10^-N;
    end
end

但是,在带有numpy的Anaconda安装上使用Python 3.8.12,此代码不会终止(请参阅Update,代码确实执行):

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

solns = np.zeros((9, 1))

for N in range(len(solns)):
    for _ in range(10**N):
        solns[N] += (10**-N)

Python代码中是否有错误,或者创建此结果的语言之间是否存在显着性差异。

编辑:

我让python代码运行了一段时间,它在230秒后就结束了。整个数组只打印为1,1,1,等等。

作为参考,使用MATLAB上的tic toc命令,程序在0.155760秒内执行。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2022-02-12 22:49:38

你在那里滥用NumPy。特别是带有数组元素的+=似乎几乎所有时间都在使用。

我就是这样做的,大概要0.5秒:

代码语言:javascript
运行
复制
from itertools import repeat

for N in range(9):
    print(sum(repeat(10**-N, 10**N)))

输出(在网上试试!):

代码语言:javascript
运行
复制
1
0.9999999999999999
1.0000000000000007
1.0000000000000007
0.9999999999999062
0.9999999999980838
1.000000000007918
0.99999999975017
1.0000000022898672

正如@AndrasDeak评论的那样,由于几个优化,它速度很快。让我们也尝试更少的优化。

首先,只需要去掉NumPy,使用简单的。你的原版也花了我230秒。只有29秒钟:

代码语言:javascript
运行
复制
for N in range(9):
    total = 0
    for _ in range(10**N):
        total += (10**-N)
    print(total)

接下来,不要一次又一次地重新计算增加值。大约需要11秒:

代码语言:javascript
运行
复制
for N in range(9):
    total = 0
    add = 10**-N
    for _ in range(10**N):
        total += add
    print(total)

接下来,摆脱产生大量int对象的range,没有很好的理由。让我们使用itertools.repeat,它是我所知道的最快的迭代。大约需要9秒:

代码语言:javascript
运行
复制
from itertools import repeat

for N in range(9):
    total = 0
    add = 10**-N
    for _ in repeat(None, 10**N):
        total += add
    print(total)

或者,或者,大致相同的速度:

代码语言:javascript
运行
复制
from itertools import repeat

for N in range(9):
    total = 0
    for add in repeat(10**-N, 10**N):
        total += add
    print(total)

只需将其放入一个函数中,以使局部变量比全局变量更快地受益。大约需要3.3秒:

代码语言:javascript
运行
复制
from itertools import repeat

def run():
    for N in range(9):
        total = 0
        for add in repeat(10**-N, 10**N):
            total += add
        print(total)
run()

这可能是我用一个普通的干净的for循环所能做的最快的(循环展开会帮助更多,但是呃.)。

我的sum(repeat(...))版本允许C代码完成所有工作(甚至sum甚至优化 优化 浮标之和),使其速度更快一些。

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

https://stackoverflow.com/questions/71096422

复制
相关文章

相似问题

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