【问题标题】:Does the length of a variable's name affect the speed the program will run?变量名称的长度会影响程序运行的速度吗?
【发布时间】:2019-05-02 17:31:42
【问题描述】:

我有一小段代码需要运行很长时间。我想知道我使用的变量名称的长度是否会改变程序执行的速度。这是一个用 Python 编写的非常简单的示例。

程序 A

    x = 1
    while not x == 0:
          print('message')

程序 B

    xyz = 1
    while not xyz == 0:
          print('message')

如果我在两台相同的机器上运行程序 A 和程序 B 30 年,程序 A 打印“消息”的次数会比程序 B 多。

【问题讨论】:

  • 过早的优化问题,让你的代码可读而不是担心这些事情

标签: python performance naming-conventions naming-containers


【解决方案1】:

@chepner 提到的结果是正确的,Python 在控制台中运行代码可能需要更长的时间,但是一旦编译代码,结果是一样的。

为了确保这是正确的,我创建了以下代码,同样受到@knifer 的回答的启发:

from time import time
from numpy import average,std

x                                              = 1
xyzabcdexyzabcdefghidjakeldkjlkfghidjakeldkjlk = 1

short_runs = 0
long_runs  = 0

for _ in range(int(2e7)):
    
    t0 = time()
    if x:
        pass
    short_runs += time() - t0
    
    t0 = time()
    if xyzabcdexyzabcdefghidjakeldkjlkfghidjakeldkjlk:
        pass
    long_runs  += time() - t0

print('Runtime results:')
print(f"Small variable runs : (sum = {short_runs:.3f})")
print(f"Long  variable runs : (sum = {long_runs :.3f})")

我提出的代码有些不同,因为试验运行的长变量名和短变量名是交织在一起的,这样可以最大限度地减少由底层操作系统进程引起的任何差异。

代码的结果会有所不同,具体取决于您是将代码copy-paste 放入 Python 控制台,还是将代码作为程序调用 (python trial_runs.py)。使用copy-paste 运行时,使用长变量名称往往会更慢,而将代码作为程序调用会产生相同的运行时间。

PS。对我来说,实际运行时间一直在变化(在一个方向或另一个方向),所以很难报告准确的值。即使是长变量名有时也可以运行得更快,尽管这在 Python 控制台上非常罕见。最大的结论是,无论哪种方式,任何差异都非常小:)

【讨论】:

    【解决方案2】:

    差异很小,我们不能断定这是因为变量的名称。

    import timeit
    x=1
    xyz=1
    
    
    start_time = timeit.default_timer()
    for i in range(1,1000000):
        if x==1:
            print("message")
    elapsed = timeit.default_timer() - start_time
    
    
    start_time2 = timeit.default_timer()
    for i in range(1,1000000):
        if xyz==1:
            print("message")
    
    elapsed2 = timeit.default_timer() - start_time2
    
    print("small variable printing = ",str(elapsed),"big variable printing = "+str(elapsed2))
    

    结果是:

    small variable printing =  3.6490847053481588 big variable printing = 3.7199463989460435
    

    【讨论】:

    • 我进行了类似的测试,结果各不相同。有两件事可以使测试对我的情况更准确,我可能应该包括,在每次迭代中为变量 message 分配一个新值(即使每次都是相同的值),并且迭代应该是 1,000,000,000 的数量级因为我的实际程序运行时间约为 7.97EE13。
    • Python 脚本的运行速度可能会因当时正在执行的底层操作系统进程而异。最好对每种情况多次运行代码进行统计分析,最好包裹在function 中。如果只在控制台运行一个小for-loop,Python会一直重新解释代码,确实可以增加运行时间(如果变量名很长的话)。但正如@chepner 之前提到的,一旦 Python 已经将程序编译为字节码,这些差异将不存在。
    【解决方案3】:

    不,名称本身对生成的代码的运行速度没有影响。变量名仅用于在 Python 源代码中区分两个由整数索引表示的变量到查找表中:

    >>> dis.dis('x=1')
      1           0 LOAD_CONST               0 (1)
                  2 STORE_NAME               0 (x)
                  4 LOAD_CONST               1 (None)
                  6 RETURN_VALUE
    >>> dis.dis('xyz=1')
      1           0 LOAD_CONST               0 (1)
                  2 STORE_NAME               0 (xyz)
                  4 LOAD_CONST               1 (None)
                  6 RETURN_VALUE
    >>> dis.dis('x=1;xyz=2;')
      1           0 LOAD_CONST               0 (1)
                  2 STORE_NAME               0 (x)
                  4 LOAD_CONST               1 (2)
                  6 STORE_NAME               1 (xyz)
                  8 LOAD_CONST               2 (None)
                 10 RETURN_VALUE
    

    在前两个中,您会注意到在生成的字节码中没有区别变量名。最后,您会看到字节码区分这两者,但仅根据定义它们的顺序,而不是标签的长度。

    【讨论】:

    • 代码多久会根据我给它的名称将值分配给整数?每次为变量分配新值时都会发生这种情况吗?对不起,如果我是多余的,我只是真的想确保我理解。我的代码围绕 2 个变量和一个生成极高阶循环组的顺序函数工作。高到足以生成整个组需要数年时间,因此强调了优化的重要性。
    • 只有一次,当源被编译成字节码时。该过程在您开始执行之前完成。
    猜你喜欢
    • 2015-04-07
    • 2011-09-13
    • 2011-11-14
    • 1970-01-01
    • 1970-01-01
    • 2013-11-22
    • 1970-01-01
    • 1970-01-01
    • 2011-06-01
    相关资源
    最近更新 更多