gpt4 book ai didi

python - 为什么 Python3 在我的任务上比 Python2 慢很多?

转载 作者:太空狗 更新时间:2023-10-30 01:05:10 26 4
gpt4 key购买 nike

我很惊讶 Python 3.5.2Python 2.7.12 慢得多。我写了一个简单的命令行命令来计算一个巨大的 CSV 文件中的行数。

$ cat huge.csv | python -c "import sys; print(sum(1 for _ in sys.stdin))"
101253515
# it took 15 seconds

$ cat huge.csv | python3 -c "import sys; print(sum(1 for _ in sys.stdin))"
101253515
# it took 66 seconds

Python 2.7.12 耗时 15 秒,Python 3.5.2 耗时 66 秒。我预计可能会发生差异,但为什么差异如此之大? Python 3 中的哪些新特性使其在执行此类任务时速度变慢了很多?有没有更快的方法来计算 Python 3 中的行数?

我的 CPU 是 Intel(R) Core(TM) i5-3570 CPU @ 3.40GHz

huge.csv 的大小为 18.1 Gb,包含 101253515 行。

问这个问题,我不需要不惜一切代价准确地找到一个大文件的行数。我刚刚写了一个 Python 3 慢得多的特殊案例。实际上,我正在用 Python 3 开发一个脚本来处理大的 CSV 文件,有些操作不需要使用 csv 库。我知道,我可以用 Python 2 编写脚本,而且速度可以接受。但我想知道一种在 Python 3 中编写类似脚本的方法。这就是为什么我对在我的示例中使 Python 3 变慢的原因以及如何通过“诚实的”python 方法改进它感兴趣。

最佳答案

sys.stdin 对象在 Python3 中比在 Python2 中复杂一点。例如,默认情况下从 Python3 中的 sys.stdin 读取将输入转换为 unicode,因此它在非 unicode 字节上失败:

$ echo -e "\xf8" | python3 -c "import sys; print(sum(1 for _ in sys.stdin))"

Traceback (most recent call last):
File "<string>", line 1, in <module>
File "<string>", line 1, in <genexpr>
File "/usr/lib/python3.5/codecs.py", line 321, in decode
(result, consumed) = self._buffer_decode(data, self.errors, final)
UnicodeDecodeError: 'utf-8' codec can't decode byte 0xf8 in position 0: invalid start byte

请注意,Python2 对该输入没有任何问题。因此,正如您所见,Python3 的 sys.stdin 在幕后做了更多事情。我不确定这是否正是造成性能损失的原因,但您可以通过在 Python3 下尝试 sys.stdin.buffer 来进一步调查它:

import sys
print(sum(1 for _ in sys.stdin.buffer))

请注意 .buffer 在 Python2 中不存在。我做了一些测试,我没有看到 Python2 的 sys.stdin 和 Python3 的 sys.stdin.buffer 之间的性能真正差异,但是 YMMV。

编辑 以下是我机器上的一些随机结果:ubuntu 16.04、i7 cpu、8GiB RAM。首先是一些 C 代码(作为比较的基础):

#include <unistd.h>

int main() {
char buffer[4096];
size_t total = 0;
while (true) {
int result = ::read(STDIN_FILENO, buffer, sizeof(buffer));
total += result;
if (result == 0) {
break;
}
}
return 0;
};

现在的文件大小:

$ ls -s --block-size=M | grep huge2.txt 
10898M huge2.txt

和测试:

// a.out is a simple C equivalent code (except for the final print)
$ time cat huge2.txt | ./a.out

real 0m20.607s
user 0m0.236s
sys 0m10.600s


$ time cat huge2.txt | python -c "import sys; print(sum(1 for _ in sys.stdin))"
898773889

real 1m24.268s
user 1m20.216s
sys 0m8.724s


$ time cat huge2.txt | python3 -c "import sys; print(sum(1 for _ in sys.stdin.buffer))"
898773889

real 1m19.734s
user 1m14.432s
sys 0m11.940s


$ time cat huge2.txt | python3 -c "import sys; print(sum(1 for _ in sys.stdin))"
898773889

real 2m0.326s
user 1m56.148s
sys 0m9.876s

所以我使用的文件有点小,时间也更长(看来你有一台更好的机器,我对更大的文件没有耐心 :D )。不管怎样,Python2 和 Python3 的 sys.stdin.buffer 在我的测试中非常相似。 Python3 的 sys.stdin 要慢得多。而且它们都落后于 C 代码(几乎为 0 用户时间)。

关于python - 为什么 Python3 在我的任务上比 Python2 慢很多?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47158071/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com