读取PyPy3中许多输入的最快方法,BytesIO在这里做什么?

问题描述 投票:0回答:2

最近我正在解决一个问题,该问题要求我阅读许多行数字(大约500,000)。

早期,我发现使用input()太慢了。使用stdin.readline()更好。但是,它仍然不够快。我发现使用以下代码:

import io, os
input = io.BytesIO(os.read(0,os.fstat(0).st_size)).readline

并且以这种方式使用input()改善了运行时间。但是,我实际上并不了解这段代码是如何工作的。在os.read(0,os.fstat(0).st_size)中阅读os.read,0的文档描述了我们正在读取的文件。 0描述什么文件?另外,fstat描述了我们正在读取的文件的状态,但是很显然,输入是否表示我们正在读取的最大字节数?

该代码有效,但是我想了解它在做什么以及为什么它更快。任何帮助表示赞赏。

python-3.x pypy
2个回答
1
投票

0是标准输入的文件描述符。 os.fstat(0).st_size会告诉Python标准输入缓冲区中当前正在等待多少字节。然后,os.read(0, ...)将再次从标准输入中批量读取那么多字节,产生一个字节串。

(另外,1是标准输出的文件描述符,2是标准错误。]

这里是一个演示:

echo "five" | python3 -c "import os; print(os.stat(0).st_size)"
# => 5

Python在标准输入缓冲区中找到了四个单字节字符和一个换行符,并报告了五个字节等待读取。

如果想要文本,字节串不是很方便使用-一方面,它们并不真正理解“行”的概念-因此BytesIO用传递的字节串伪造了输入流,使您可以[C0 ] 从中。我不确定100%为什么会更快,但是我的猜测是:

  • 正常读取很可能是按字符进行的,因此无需过多读取就可以检测到换行和停止;批量读取效率更高(而且在内存中查找事实后的换行符非常快)]
  • 没有这种方式的编码处理

1
投票

readline具有签名,我正在呼叫os.readfd。将size设置为size剩余的字节会导致其他所有内容像图斯南一样冲向您。也有0 = stdin,1 = stdout,2 = stderr的“标准文件描述符”。

解构代码:

fd
© www.soinside.com 2019 - 2024. All rights reserved.