python read() from stdout 比逐行读取慢得多(吞咽?)

标签 python performance subprocess readline

我有一个运行可执行文件并将输出通过管道传输到我的子进程标准输出的 python SubProcess 调用。

在 stdout 数据相对较小(~2k 行)的情况下,逐行读取和作为一个 block 读取(stdout.read())之间的性能是可比较的......而 stdout.read() 稍微更快。

一旦数据变大(比如 30k+ 行),逐行读取的性能就会明显提高。

这是我的比较脚本:

proc=subprocess.Popen(executable,stdout=subprocess.PIPE)
tic=time.clock()
for line in (iter(proc.stdout.readline,b'')):
    tmp.append(line)
print("line by line = %.2f"%(time.clock()-tic))

proc=subprocess.Popen(executable,stdout=subprocess.PIPE)
tic=time.clock()
fullFile=proc.stdout.read()
print("slurped = %.2f"%(time.clock()-tic))

这些是读取 ~96k 行(或 50mb 磁盘内存)的结果:

line by line = 5.48
slurped = 153.03

我不清楚为什么性能差异如此之大。我的期望是 read() 版本应该比逐行存储结果更快。当然,在实际情况下,我期待更快的逐行结果,因为在读取过程中可以完成大量的每行处理。

谁能告诉我 read() 的性能成本?

最佳答案

这不仅仅是 Python,没有缓冲的字符读取总是比读入行或大块慢。

考虑这两个简单的 C 程序:

[读取字符.c]

#include <stdlib.h>
#include <stdio.h>
#include <errno.h>

int main(void) {
        FILE* fh = fopen("largefile.txt", "r");
        if (fh == NULL) {
                perror("Failed to open file largefile.txt");
                exit(1);
        }

        int c;
        c = fgetc(fh);
        while (c != EOF) {
                c = fgetc(fh);
        }

        return 0;
}

[readlines.c]

#include <stdlib.h>
#include <stdio.h>
#include <errno.h>

int main(void) {
        FILE* fh = fopen("largefile.txt", "r");
        if (fh == NULL) {
                perror("Failed to open file largefile.txt");
                exit(1);
        }

        char* s = (char*) malloc(120);
        s = fgets(s, 120, fh);
        while ((s != NULL) && !feof(fh)) {
                s = fgets(s, 120, fh);
        }

        free(s);

        return 0;
}

他们的结果(YMMW,largefile.txt 是 ~200MB 文本文件):

$ gcc readchars.c -o readchars
$ time ./readchars            
./readchars  1.32s user 0.03s system 99% cpu 1.350 total
$ gcc readlines.c -o readlines
$ time ./readlines            
./readlines  0.27s user 0.03s system 99% cpu 0.300 total

关于python read() from stdout 比逐行读取慢得多(吞咽?),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21386464/

相关文章:

performance - 10,000 个静态立方体的 OpenGL 性能

python - 在 Python (NumPy) 中高效计算相似度矩阵

sql - 内连接 vs 内连接

python - 如何使用 shell = true 通过 Python subprocess.Popen() 将 SIGINT 传递给子进程

python - 将 Excel 转换为 pdf 时 Excel.Application.Workbooks 属性错误

python - Matplotlib 绘制多条线不起作用

python - 如何使用 python subprocess 命令在不同目录中运行 shell 命令?

python - 使用参数在 Python 中执行 Fortran 子进程

python - Keras TimeDistributed - 权重共享吗?

Python print_r 返回值而不是打印它