【问题标题】:Why my implementation of aks prime test is slower than my implementation of the naive version? [closed]为什么我的 aks prime 测试的实现比我的幼稚版本的实现慢? [关闭]
【发布时间】:2021-09-18 11:28:37
【问题描述】:

我尝试比较多种算法以找到“i”下的最大素数。 但是当我测试实现时,“aks”比我幼稚的实现要慢。 我在想 aks 是一个更好的素数测试实现,我弄错了吗?

 def expand_x_1(n): 
    c =1
    for i in range(n//2+1):
        c = c*(n-i)//(i+1)
        yield c
 
def aks(p):
    if p==2:
        return True
 
    for i in expand_x_1(p):
        if i % p:
            return False
    return True

def all_factors(x): # naive version
    i = 2
    s = int(x ** 0.5)
    while i < s:
        if x % i == 0:
            return False
        i += 1
    return True

def find(i, func) :
    while not func(i) :
        i -= 1
    print(i)

%time find(2**16, aks)
%time find(2**16, all_factors)

我尝试比较两者并获得:

  • 为阿克斯
65521
CPU times: user 1.7 s, sys: 3.24 ms, total: 1.7 s
Wall time: 1.7 s
  • for all_factor
65521
CPU times: user 81 µs, sys: 0 ns, total: 81 µs
Wall time: 83.9 µs

【问题讨论】:

  • 您使用两个单独的值调用它们。是什么让您认为这两个测试用例具有直接可比性?
  • 如果您使用print(i) 来查看它执行了多少次while/for 循环,那么您会看到幼稚版本的循环更少 - 因为它不使用*//所以它需要更少的时间。

标签: python cryptography primes


【解决方案1】:

当输入是素数时,expand_x_1(n) 最终会产生所有可能的n//2+1 结果,但all_factors(n) 中的循环仅循环大约sqrt(n) 次。这是一个巨大的差异。

但也很重要:

c = c*(n-i)//(i+1)

在迭代中不受限制地增长。添加

            print(c.bit_length())

yield 之前,您会看到find(65521, aks) 在完成之前对超过65000 位宽的整数进行算术运算。这也远比 16 位算法 find(65521, all_factors) 可以。

注意:实际上,没有人使用 AKS 素数测试,因为即使是由世界级数学家大规模优化的版本也比其他版本慢。有关更多信息,请参阅AKS Primes algorithm in Python

【讨论】:

    猜你喜欢
    • 2016-04-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-02-09
    • 1970-01-01
    • 1970-01-01
    • 2017-01-18
    相关资源
    最近更新 更多