python - 执行循环的时间突然增加

发布于 2024-11-28 07:00:44 字数 1062 浏览 6 评论 0原文

我有一些小软件,可以计算每个三角形数字的因子数,看看其中第一个有超过 X 个因子(是的,这是一个投影问题,数字 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

我假设如果我继续,我会遇到系统调用增加和时间突然增加的其他点,以前也有类似的点,但时间太短了,所以并不重要。为什么函数调用突然增加?难道不是应该再次调用该函数以获得新值吗?

PS我使用cProfile作为分析器,这里代码中的X只是为了演示,我直接在代码中写入值...提前谢谢...

I have some small piece of software that calculates the number of factors of each triangle number to see what is the first one of them has more than X number of factors (yes, it's a projecteuler problem, number 12,, although i didn't solve it yet)... as am trying making X some random values to see what the code does and in how much time, I noticed something strange (to me at least): until X=47 the execution time increases in obviously normal way, but when X = 48 it increases more than normal, and function calls are much greater than the rate, it (explodes) if I would say that.. why does it do that??

the code:

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

and when profiling:

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

I assume that if I continued I would meet other points that system calls increases and time increases suddenly, and previously there were points like that but time was so small so it did't matter so much.. Why function calls suddenly increases?? Isn't it supposed just to call the function one more time for the new value??

P.S. am using cProfile as a profiler, and X in the code here is just for demonstration, I write the value directly in the code... thank you in advance...

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

流绪微梦 2024-12-05 07:00:44

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

第一个超过 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 之间的所有数字?)
  • 三角形数有多少个约数? (看一些小的三角数,您可以在其中计算答案。)您能看到任何可以帮助您计算更大三角数答案的模式吗?

Have you looked at the actual values involved?

The first triangular number with more than 47 factors is T(104) = 5460, which has 48 factors.

But the first triangular number with more than 48 factors is T(224) = 25200, which has 90 factors. So no wonder it takes a lot more work.

If your code runs up to T(n), then it calls range 2n times and fac n times, for a total of 3n function calls. Thus for T(104) it requires 312 function calls, and for T(224) it requires 672 function calls. Presumably there are 2 function calls of overhead somewhere that you're not showing us, which explains the profiling results you get.


Your current strategy is not going to get you to the answer for the Project Euler problem. But I can give some hints.

  • Do you have to start over again with summ=0 each time you compute a triangular number?
  • Do you have to loop over all the numbers up to n in order to work out how many divisors it has? Could there be a quicker way? (How many divisors does 216 = 65536 have? Do you have to loop over all the numbers from 1 to 65536?)
  • How many divisors do triangular numbers have? (Look at some small triangular numbers where you can compute the answer.) Can you see any patterns that would help you compute the answer for much bigger triangular numbers?
看轻我的陪伴 2024-12-05 07:00:44

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

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

注意:Euler 是数学网站,请勿编写暴力算法;)

If you check the output you'll see several spikes (sudden increasement) in execution time.

The reason is that the number of loops needed is not going up gradually but abruptly. Print out n after you while True loop and you'll see it.

Note: Euler is math site, don't write brute force algorithms ;)

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文