【问题标题】:python - time to execute a loop increases suddenlypython - 执行循环的时间突然增加
【发布时间】:2011-08-06 23:27:13
【问题描述】:

我有一些小软件可以计算每个三角形数的因子数,以查看其中的第一个因子数超过 X(是的,这是一个投影仪问题,number 12,虽然我还没有解决它)...当我尝试使 X 一些随机值以查看代码的作用和时间时,我注意到一些奇怪的事情(至少对我来说):直到 X=47 执行时间增加以明显正常的方式,但是当 X = 48 它比正常增加更多,并且函数调用远大于速率,如果我这么说它(爆炸).. 为什么它会这样做??

代码:

def fac(n):
    c=0
    for i in range (1,n+1):
        if n%i==0:
            c=c+1
    return c

n=1

while True:
    summ=0
    for i in range (1,n+1):
        summ=summ+i
    if fac(summ)>X:
        break
    n=n+1

print summ

分析时:

when X=45 :  314 function calls in 0.027 CPU seconds
when X=46 :  314 function calls in 0.026 CPU seconds
when X=47 :  314 function calls in 0.026 CPU seconds
when X=48 :  674 function calls in 0.233 CPU seconds
when X=49 :  674 function calls in 0.237 CPU seconds

我假设如果我继续我会遇到系统调用增加和时间突然增加的其他点,以前有这样的点但是时间太小所以没那么重要..为什么函数调用突然增加??不是应该为新值再调用一次函数吗?

附:我用cProfile作为profiler,这里代码中的X只是为了演示,我直接把值写在代码里...先谢谢大家了...

【问题讨论】:

  • 我在问突然的性能差异是否可能是由于调用了垃圾收集器。我只是猜测。
  • @Chris:这里不能解释垃圾收集,因为 Python 的垃圾收集器 only runs when excess allocations exceed a threshold。这里给出的代码不会累积分配的数据,所以不会达到阈值,也不会调用收集器。
  • 确实如此。整数是不可变的,因此c=c+1 语句确实会在内存中累积。不过我承认这是一个非常的积累。我再说一遍:这是一个猜测。
  • @Chris:即使整数是不可变的,它们的内存仍然会被重用。

标签: python loops time function-calls


【解决方案1】:

您是否查看过所涉及的实际值?

第一个超过 47 个因子的三角形数是 T(104) = 5460,它有 48 个因子。

但是第一个超过 48 个因子的三角数是 T(224) = 25200,它有 90 个因子。所以难怪它需要更多的工作。

如果您的代码运行到 T(n),那么它会调用 range 2n 次和 fac n 次,总共 3n 次函数调用。因此,对于 T(104),它需要 312 个函数调用,而对于 T(224),它需要 672 个函数调用。大概有 2 个开销函数调用您没有向我们展示,这解释了您得到的分析结果。


您当前的策略不会让您找到欧拉计划问题的答案。但我可以给出一些提示。

  • 每次计算三角数时,是否都必须使用 summ=0 重新开始?
  • 您是否必须遍历直到 n 的所有数字才能计算出它有多少个除数?有没有更快的方法? (216 = 65536 有多少个除数?你必须循环从 1 到 65536 的所有数字吗?)
  • 三角数有多少个除数? (查看一些可以计算答案的小三角数。)您能找到任何有助于计算更大三角数答案的模式吗?

【讨论】:

  • 是的..函数调用(爆炸)的这些点是数字实际发生变化的时候..我很傻,没有注意到:)
  • 和 +1 的笔记,特别是 no.3
【解决方案2】:

如果您检查输出,您会看到执行时间出现几个峰值(突然增加)。

原因是所需的循环数不是逐渐增加而是突然增加。在while True 循环之后打印出n,你会看到它。

注意:Euler 是数学网站,不要编写蛮力算法;)

【讨论】:

    猜你喜欢
    • 2018-02-13
    • 2014-07-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-10-15
    • 1970-01-01
    • 2011-03-13
    • 2019-02-02
    相关资源
    最近更新 更多