zoukankan      html  css  js  c++  java
  • Python2中while 1比while True更快

    1) bool类是从int类继承而来的

    2) True/False 在python2中不是关键字,但是在python3是(True,False,None)

    PS > python2
    Enthought Canopy Python 2.7.11 | 64-bit | (default, Jun 11 2016, 11:33:47) [MSC v.1500 64 bit (AMD64)] on win32
    Type "help", "copyright", "credits" or "license" for more information.
    >>> import keyword
    >>> keyword.kwlist
    ['and', 'as', 'assert', 'break', 'class', 'continue', 'def', 'del', 'elif', 'else', 'except', 'exec', 'finally', 'for',
    'from', 'global', 'if', 'import', 'in', 'is', 'lambda', 'not', 'or', 'pass', 'print', 'raise', 'return', 'try', 'while',
     'with', 'yield']
    >>>
    
    PS > python3
    Python 3.5.2 (v3.5.2:4def2a2901a5, Jun 25 2016, 22:01:18) [MSC v.1900 32 bit (Intel)] on win32
    Type "help", "copyright", "credits" or "license" for more information.
    >>> import keyword
    >>> keyword.kwlist
    ['False', 'None', 'True', 'and', 'as', 'assert', 'break', 'class', 'continue', 'def', 'del', 'elif', 'else', 'except', '
    finally', 'for', 'from', 'global', 'if', 'import', 'in', 'is', 'lambda', 'nonlocal', 'not', 'or', 'pass', 'raise', 'retu
    rn', 'try', 'while', 'with', 'yield']
    >>>

    由于Python2中True/False不是关键字,因此我们可以对其进行任意的赋值

    >>> True="test"
    >>> True
    'test'
    >>> "test"==True
    True
    >>> 1==True
    False
    >>>

    3) 由于bool是继承自int的子类,因此为了保证向下兼容性,在进行算术运算中,True/False会被当作int值来执行

    >>> del True
    >>> True+True
    2
    >>> False + False
    0
    >>>

    4)While 1 比While True快

    import timeit
    
    def while_one():
        i=0
        while 1:
            i+=1
            if i==10000000:
                break
    
    def while_true():
        i=0
        while True:
            i+=1
            if i==10000000:
                break
                
    if __name__=="__main__":
        t1=timeit.timeit(while_one,"from __main__ import while_one",number=3)
        t2=timeit.timeit(while_true,"from __main__ import while_true", number=3)
        #t1=timeit.timeit(while_one,"from __main__ import while_one",number=3)
        print "while one : %s 
    while true: %s " % (t1,t2)
    
    
    while one : 1.16112167105 
    while true: 1.66502957924 

    原因就是前提中提到的关键字的问题。由于Python2中,True/False不是关键字,因此我们可以对其进行任意的赋值,这就导致程序在每次循环时都需要对True/False的值进行检查;而对于1,则被程序进行了优化,而后不会再进行检查。

    我们可以通过dis模块来查看while_one和while_true的字节码

    import dis
    
    def while_one():
        while 1:
            pass
            
    def while_true():
        while True:
            pass
            
    if __name__=="__main__":
        print "while_one 
    "
        dis.dis(while_one)
        
        print "while_true 
    "
        dis.dis(while_true)
        

    结果:

    while_one 
    
      4           0 SETUP_LOOP               4 (to 7)
    
      5     >>    3 JUMP_ABSOLUTE            3
                  6 POP_BLOCK           
            >>    7 LOAD_CONST               0 (None)
                 10 RETURN_VALUE        
    while_true 
    
      8           0 SETUP_LOOP              10 (to 13)
            >>    3 LOAD_GLOBAL              0 (True)
                  6 POP_JUMP_IF_FALSE       12
    
      9           9 JUMP_ABSOLUTE            3
            >>   12 POP_BLOCK           
            >>   13 LOAD_CONST               0 (None)
                 16 RETURN_VALUE     

    可以看出,正如上面所讲到的,在while True的时候,字节码中多出了几行语句,正是这几行语句进行了True值的检查

    而在Python3中,由于True/False已经是关键字了,不允许进行重新赋值,因此,其执行结果与while 1不再有区别

     PS > python3
     Python 3.5.2 (v3.5.2:4def2a2901a5, Jun 25 2016, 22:01:18) [MSC v.1900 32 bit (Intel)] on win32
     Type "help", "copyright", "credits" or "license" for more information.

    >>> from test_while import *
    >>> t1=timeit.timeit(while_one,"from __main__ import while_one",number=3)
    >>> t2=timeit.timeit(while_true,"from __main__ import while_true", number=3)
    >>> t1
    3.1002996925072743
    >>> t2
    3.077654023474544

    5) if x==True or if x:

    后者比前者快

    #! python2
    #-*- coding:utf-8 -*-
    
    import timeit
    
    def if_x_eq_true():
        x=True
        if x==True:
            pass
            
    def if_x():
        x=True
        if x:
            pass
            
    if __name__=="__main__":
        t1=timeit.timeit(if_x_eq_true,"from __main__ import if_x_eq_true", number=1000000)
        t2=timeit.timeit(if_x,"from __main__ import if_x",number=1000000)
        print "if_x_eq_true: %s 
     if_x: %s" % (t1,t2)
    
    
    if_x_eq_true: 0.186029813246 
    if_x: 0.120894725822

    字节码:

    import dis
    
    def if_x_eq_true():
        x=True
        if x==True:
            pass
            
    def if_x():
        x=True
        if x:
            pass   
    
    if __name__=="__main__":
        print "if_x_eq_true 
    "
        dis.dis(if_x_eq_true)
        
        print "if_x 
    "
        dis.dis(if_x)

    结果

    if_x_eq_true 
    
      4           0 LOAD_GLOBAL              0 (True)
                  3 STORE_FAST               0 (x)
    
      5           6 LOAD_FAST                0 (x)
                  9 LOAD_GLOBAL              0 (True)
                 12 COMPARE_OP               2 (==)
                 15 POP_JUMP_IF_FALSE       21
    
      6          18 JUMP_FORWARD             0 (to 21)
            >>   21 LOAD_CONST               0 (None)
                 24 RETURN_VALUE        
    if_x 
    
      9           0 LOAD_GLOBAL              0 (True)
                  3 STORE_FAST               0 (x)
    
     10           6 LOAD_FAST                0 (x)
                  9 POP_JUMP_IF_FALSE       15
    
     11          12 JUMP_FORWARD             0 (to 15)
            >>   15 LOAD_CONST               0 (None)
                 18 RETURN_VALUE        
  • 相关阅读:
    哎~水题,还是最小生成树。没想到一遍AC了...
    博客搬家咯~
    又遇到一个奇葩问题....输出double用%f...
    又想吐槽一下了...同样是DP,差别咋就那么大呢?
    1487: 未覆盖顶点数量.
    并查集~
    侃项目管理 序
    安装Redis报错jemalloc/jemalloc.h: No such file or directory
    PyCharm设置pip国内源(镜像)
    HBase元数据及损坏文件的修复
  • 原文地址:https://www.cnblogs.com/dadadechengzi/p/6269585.html
Copyright © 2011-2022 走看看