Python中哪个动作更快?

2024-04-26 04:59:20 发布

您现在位置:Python中文网/ 问答频道 /正文

当试图求正整数n除以10的余数时,这两个动作中哪一个更快?为什么?你知道吗

print(n%10) #1st method

print(str(n)[-1]) #2nd method

Tags: methodprint动作str正整数
3条回答

第二个大约需要3倍的时间。我还没有仔细阅读源代码,但可能是因为类型转换和切片,而第一个是一个简单的、定义良好的操作。你知道吗

import time
def timeit(f, n):
    start = time.time()
    for i in range(n):
            f(n)
    return time.time()-start

def f1(n):
    return n % 10

def f2(n):
    return str(n)[-1]

mean = lambda a: sum(a)/len(a)

>>> mean([timeit(f1, 1000000) for i in range(10)]) #average 10 runs
0.111114501953125
>>> mean([timeit(f2, 1000000) for i in range(10)]) #average 10 runs
0.29976160526275636
>>> 

你不在乎。你知道吗

在实际项目中,这种差异是完全可以忽略的,因为有太多的事情比寻找剩余物慢得多,其中有些涉及IO,有些涉及复杂的算法。你知道吗

在您的情况下,您应该只考虑代码可读性。第一种方法的可读性比第二种方法好得多。你知道吗

原件

判断哪个更快的方法是使用timeit。你知道吗

python -m timeit '4658746110%10'
100000000 loops, best of 3: 0.0142 usec per loop
python -m timeit 'str(4658746110)[-1]'
1000000 loops, best of 3: 0.219 usec per loop

编辑

就像注释所说的,如果你写4658746110%10,它将被常数折叠成0。你知道吗

在python中,我们可以使用dis模块来查看字节码。你知道吗

import dis

def test(n):
    for i in range(n):
        4658746110 % 10

dis.dis(test)
  4           0 SETUP_LOOP              20 (to 22)
              2 LOAD_GLOBAL              0 (range)
              4 LOAD_FAST                0 (n)
              6 CALL_FUNCTION            1
              8 GET_ITER
        >>   10 FOR_ITER                 8 (to 20)
             12 STORE_FAST               1 (i)

  5          14 LOAD_CONST               3 (0)
             16 POP_TOP
             18 JUMP_ABSOLUTE           10
        >>   20 POP_BLOCK
        >>   22 LOAD_CONST               0 (None)
             24 RETURN_VALUE

constant数字改成i

  4           0 SETUP_LOOP              24 (to 26)
              2 LOAD_GLOBAL              0 (range)
              4 LOAD_FAST                0 (n)
              6 CALL_FUNCTION            1
              8 GET_ITER
        >>   10 FOR_ITER                12 (to 24)
             12 STORE_FAST               1 (i)

  5          14 LOAD_FAST                1 (i)
             16 LOAD_CONST               1 (10)
             18 BINARY_MODULO
             20 POP_TOP
             22 JUMP_ABSOLUTE           10
        >>   24 POP_BLOCK
        >>   26 LOAD_CONST               0 (None)
             28 RETURN_VALUE

第一个是LOAD_CONST,第二个是BINARY_MODULO。所以你想要计时的代码可能是这样的:

python -m timeit '[n%10 for n in range(100000000)]'
10 loops, best of 3: 5.82 sec per loop
python -m timeit '[str(n)[-1] for n in range(100000000)]'
10 loops, best of 3: 20.9 sec per loop

相关问题 更多 >