为什么在这种情况下使用发电机功能的速度是原来的两倍?

Sar*_*lli 10 python performance generator

这两个实现共同的代码:

from math import sqrt

def factors(x):
    num = 2
    sq = int(sqrt(x))
    for i in range(2, sq):
        if (x % i) == 0:
            num += 2
    return num + ((1 if sq == sqrt(x) else 2) if x % sq == 0 else 0)
Run Code Online (Sandbox Code Playgroud)

1.不使用发电机功能的实施:

i = 1
while True:
    if factors(i * (i+1) * 0.5) > 500:
        print(int(i * (i+1) * 0.5))
        break
    i += 1
Run Code Online (Sandbox Code Playgroud)

2.利用发电机功能的实施:

def triangle():
    i = 1
    while True:
        yield int(0.5 * i * (i + 1))
        i += 1

t = triangle()

while True:
    num = t.__next__()
    if factors(num) > 500:
        print(num)
        break
Run Code Online (Sandbox Code Playgroud)

问题:

第一个实现大约需要4秒,而第二个大约需要8.2秒.为什么两个实现的运行时间之间有这么大的差异?

Pru*_*Raj 11

temp1中():

def temp1():
        i = 1
        while True:
            if factors(i * (i+1) * 0.5) > 500:
                print(int(i * (i+1) * 0.5))
                break
            i += 1
Run Code Online (Sandbox Code Playgroud)

TEMP2():

def temp2():
    def triangle():
        i = 1
        while True:
            yield int(0.5 * i * (i + 1))
            i += 1

    t = triangle()

    while True:
        num = t.next()
        if factors(num) > 500:
            print(num)
            break
Run Code Online (Sandbox Code Playgroud)

c两者的配置文件:

在此输入图像描述 改变后factors的调用temp1()factors(int(...)),事实证明,temp1()采取类似的时间

Modified temp1 to pass int rather than float:

def temp1():
    i = 1
    while True:
        if factors(int(i * (i+1) * 0.5)) > 500:
            print(int(i * (i+1) * 0.5))
            break
        i += 1
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述

所以事实证明,在你的第一个实现中,你传递floatfactors()浮点运算比整数运算复杂

为什么浮点运算很复杂?

因为浮点数在内部表示的方式与整数不同,它们用3个部分表示为符号,尾数和指数(IEEE 754),而整数的表示非常简单,因此整数的加法和减法操作,甚至乘法和除法在内部使用加法,减法和移位操作的组合来执行.因为整数加法和减法很简单,所以它们的除法/乘法也是如此,因此浮点运算是一些昂贵的

为什么浮点模数比Integer贵?

答案与上面的相同,模运算只不过是上面提到的原始运算的组合如下:

a mod n = a - (n*int(a/n))
Run Code Online (Sandbox Code Playgroud)

由于浮点数的原始操作更昂贵,因此浮点数也是模数


650*_*502 8

在显式情况下,您int在调用之前没有使用表达式factors,因此传递的值将是浮点数.

在生成器的情况下,你反而屈服int(...),调用factors传递一个整数.


Bin*_*nut 2

据我所知,唯一的区别是您i * (i+1) * 0.5在第一个示例中进行了两次计算。这不是一个昂贵的计算,但它可能会产生很大的影响,因为它是程序的很大一部分。