modulos和FizzBuzz的计算复杂性。

问题描述 投票:1回答:1

所以我不想去讨论这是不是FizzBuzz挑战赛最完美的代码。

对于那些不熟悉FizzBuzz的人来说,在打印出1-100的范围时有四个规则。

  1. 打印出所有的数字
  2. 如果数字被3整除,打印 "Fizz "代替。
  3. 如果数字被5整除,就打印 "Buzz"。
  4. 如果这个数字同时被3和5整除,则打印 "FizzBuzz")。)

我运行了两个实现,来比较它们的速度。

# Code A
%%timeit
for i in range(1,10001):
    if i % 15 == 0:
        print('FizzBuzz')
    elif i % 3 == 0:
        print('Fizz')
    elif i % 5 == 0:
        print('Buzz')
    else:
        print(i)
# Code B
%%timeit
for i in range(1,10001):
    if i % 5 == 0 and i % 3 == 0:
        print('FizzBuzz')
    elif i % 3 == 0:
        print('Fizz')
    elif i % 5 == 0:
        print('Buzz')
    else:
        print(i)

尽管有额外的... if 代码B的评估,它始终比代码A跑得快。数字越大,是否会导致模数越慢?这其中的根本原因是什么?

python time-complexity complexity-theory
1个回答
3
投票

我能想到的主要原因可能是优化。

B版使用了几次同样的操作,即。

  • i mod 5
  • i mod 3

一个相当聪明的编译器解释者可能会发现这一点,并计算出这些中间结果。通过这样做,它将能够立即计算出整个if-block,而只需2次mod操作。

简而言之,我认为最终被执行的代码可能是这样的。

for i in range(1,10001):
    a = i % 5
    b = i % 3
    if a == 0 and b == 0:
        print('FizzBuzz')
    elif b == 0:
        print('Fizz')
    elif a == 0:
        print('Buzz')
    else:
        print(i)

但是,A块的代码可能太复杂了。我的意思是,编译器将总是被迫执行3次mod操作。除非它能以某种方式发现15=3*5,并利用这个逻辑来重写if语句。

© www.soinside.com 2019 - 2024. All rights reserved.