【问题标题】:python read() and write() in large blocks / memory management大块/内存管理中的python read()和write()
【发布时间】:2013-09-16 00:14:47
【问题描述】:

我正在编写一些 python 代码,将不同点的大文件拼接在一起。我在 C 中做了类似的事情,我分配了一个 1MB 字符数组并将其用作读/写缓冲区。而且很简单:将 1MB 读入 char 数组,然后写出来。

但是对于 python,我假设它是不同的,每次我调用 size = 1M 的 read() 时,它都会分配一个 1M 长的字符串。希望当缓冲区超出范围时,我们会在下一次 gc 过程中释放它。

python 会以这种方式处理分配吗?如果是这样,常量分配/释放周期的计算成本是否很高?

我可以告诉 python 使用与 C 中相同的内存块吗?还是 python vm 足够聪明,可以自己做?

我想我的主要目标有点像 dd 在 python 中的实现。

【问题讨论】:

  • 你在担心一些无关紧要的事情。 IO 慢,分配器快。在尝试优化使您的代码更复杂之前进行分析。

标签: python memory-management file-io


【解决方案1】:

在网站 docs.python.org 中搜索 readinto 以查找适合您正在使用的 Python 版本的文档。 readinto 是一个低级功能。它们看起来很像这样:

读入(b) 将最多 len(b) 个字节读入 bytearray b 并返回读取的字节数。

与 read() 一样,可以向底层原始流发出多次读取,除非后者是交互式的。

如果底层原始流处于非阻塞模式并且目前没有可用数据,则会引发 BlockingIOError。

但不要过早地担心它。 Python 以惊人的速度分配和释放动态内存,并且重复获取和释放微不足道的兆字节的成本很可能会在噪音中消失。请注意,CPython 主要是引用计数的,因此当超出范围时,您的缓冲区将“立即”回收。至于 Python 是否每次都会重用相同的内存空间,可能性是不错的,但不确定。 Python 没有尝试强制这样做,但是根据整个分配/释放模式以及系统 C 的 malloc()/free() 实现的细节,它并非不可能被重用 ;-)

【讨论】:

  • 谢谢,readinfo() 正是我想要的。出于好奇,我决定在使用 1MB 缓冲区的 300MB 文件中比较 readinfo()read()。事实证明,readinfo()read() 快 40% 左右。所以也许重新分配缓冲区的成本毕竟不是那么微不足道。
  • 有趣!我必须记住这一点;-) 很高兴它有帮助。
  • @rhlee:您是否确保在测试期间该文件没有被您的操作系统缓存?
  • @Chronial:我认为这涉及到缓存,因为在我第一次读取文件后,事情的速度显着加快。所以我放弃了前几次尝试的时间,然后平均使用了接下来的五次左右,这非常一致。
  • 所以你确定涉及到内存缓存?然后你的测量似乎跑题了,因为这是关于 IO 并且 IO 很慢,所以分配无关紧要。您测量了内存中的复制,分配当然很重要。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-03-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-11-02
  • 2017-02-15
  • 1970-01-01
相关资源
最近更新 更多