为什么网格 python 代码比分解的代码慢? [英] Why mesh python code slower than decomposed one?

查看:34
本文介绍了为什么网格 python 代码比分解的代码慢?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在调查线程时发现了令人惊讶的 Python 行为 为什么在 C++ 中从 stdin 读取行比 Python 慢得多?.

I've discovered surprising python behaviour while had investigating thread Why is reading lines from stdin much slower in C++ than Python?.

如果我从那个线程运行简单的python代码

If I run simple python code from that thread

#!/usr/bin/env python
from __future__ import print_function
import time
import sys


count = 0
start_time = time.time()

for line in sys.stdin:
    count += 1

delta_sec = time.time() - start_time
if delta_sec >= 0:
    lines_per_sec = int(round(count/delta_sec))
    print("Read {0:n} lines in {1:.2f} seconds. LPS: {2:n}".format(count, delta_sec, lines_per_sec))

它的工作速度为 11.5M LPS,当我将整个脚本分解为单个函数时

it works with speed 11.5M LPS, and when I decompose the whole script into single function

#!/usr/bin/env python
from __future__ import print_function
import time
import sys


def test(input):
    count = 0
    start_time = time.time()

    for line in input:
        count += 1

    delta_sec = time.time() - start_time
    if delta_sec >= 0:
        lines_per_sec = int(round(count/delta_sec))
        print("Read {0:n} lines in {1:.2f} seconds. LPS: {2:n}".format(count, delta_sec, lines_per_sec))


if __name__ == "__main__":
    test(sys.stdin)

代码速度高达 23M LPS.

code speeds up to 23M LPS.

为什么这种简单的重构使我的代码速度提高了 2 倍?

Why this simple refactoring makes my code 2 times faster?

我已经在 Ubuntu 13.10 上使用 python2.7 运行了我的测试.

推荐答案

观察字节码帮助我回答了这个问题.第一个脚本的工作部分的字节码是:

Watching into bytecode helped me to answer this question. Byte code for working part of the first script is:

 10          58 SETUP_LOOP              27 (to 88)
             61 LOAD_NAME                3 (sys)
             64 LOAD_ATTR                6 (stdin)
             67 GET_ITER         
        >>   68 FOR_ITER                16 (to 87)
             71 STORE_NAME               7 (line)
 11          74 LOAD_NAME                4 (count)
             77 LOAD_CONST               4 (1)
             80 INPLACE_ADD      
             81 STORE_NAME               4 (count)
             84 JUMP_ABSOLUTE           68
        >>   87 POP_BLOCK

第二个脚本对应部分的字节码是:

And byte code for corresponding part of second script is:

 12          18 SETUP_LOOP              24 (to 45)
             21 LOAD_FAST                0 (input)
             24 GET_ITER
        >>   25 FOR_ITER                16 (to 44)
             28 STORE_FAST               3 (line)
 13          31 LOAD_FAST                1 (count)
             34 LOAD_CONST               2 (1)
             37 INPLACE_ADD
             38 STORE_FAST               1 (count)
             41 JUMP_ABSOLUTE           25
        >>   44 POP_BLOCK

我看到这些代码之间的实际区别是使用 LOAD_NAME vs LOAD_FAST 和 STORE_NAME vs STORE_FAST 操作码.文档 http://docs.python.org/2.7/library/dis.html#opcode-LOAD_FAST 说LOAD_FAST 仅使用索引进行查找,而 LOAD_NAME 通过字符串名称查找变量.第一种方法快两倍.

I see that actual difference between this codes is LOAD_NAME vs LOAD_FAST and STORE_NAME vs STORE_FAST opcodes using. Documentation http://docs.python.org/2.7/library/dis.html#opcode-LOAD_FAST says that LOAD_FAST makes lookup using only indexes, while LOAD_NAME lookups variable by string name. And the first approach is two times faster.

这篇关于为什么网格 python 代码比分解的代码慢?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆