【问题标题】:Python: quickly loading 7 GB of text files into unicode stringsPython:快速将 7 GB 的文本文件加载到 unicode 字符串中
【发布时间】:2011-04-08 13:21:27
【问题描述】:

我有一个很大的文本文件目录——大约 7 GB。我需要将它们快速加载到 iPython 中的 Python unicode 字符串中。我总共有 15 GB 的内存。 (我使用的是 EC2,所以如果绝对必要,我可以购买更多内存。)

对于我的目的来说,仅仅读取文件太慢了。我尝试将文件复制到 ramdisk,然后将它们从那里加载到 iPython 中。这加快了速度,但 iPython 崩溃了(没有足够的内存剩余?)这是 ramdisk 设置:

mount -t tmpfs none /var/ramdisk -o size=7g

有人有什么想法吗?基本上,我正在寻找持久的内存中 Python 对象。 iPython 要求禁止使用 IncPy:http://www.stanford.edu/~pgbovine/incpy.html

谢谢!

【问题讨论】:

  • 您真的需要一次在内存中存储所有数据吗?真的吗?
  • 这几乎肯定是错误的做法。 Python 不是为存储大量数据而设计的。无论是几个巨大的对象还是数百万个单行字符串,它们都会以非设计的方式对 VM 施加压力。如果不解释为什么您确实需要这样做,而不是将数据加载到专为此类存储而设计的数据库后端,您将很难获得帮助。
  • 我可以使用数据库后端。你推荐哪一个?至于我是否需要内存中的所有数据,我真的不知道。我正在使用 Aho-Corasick 算法搜索子字符串。我只是认为将所有内容都记入内存是一种好习惯...

标签: python memory ctypes shared-memory ipython


【解决方案1】:

这里有很多令人困惑的地方,这使得回答这个问题变得更加困难:

  • ipython 要求。为什么需要从 ipython 而不是独立脚本中处理如此大的数据文件?
  • tmpfs RAM 磁盘。我将您的问题解读为暗示您在 Python 中一次将所有输入数据读入内存。如果是这种情况,那么无论如何,python 都会分配自己的缓冲区来保存所有数据,而 tmpfs 文件系统只有在您多次从 RAM 磁盘重新加载数据时才能为您带来性能提升。
  • 提到 IncPy。如果您的性能问题可以通过 memoization 解决,为什么不能手动为最有帮助的功能实现 memoization?

所以。如果您实际上一次需要内存中的所有数据——例如,如果你的算法多次重新处理整个数据集——我建议查看mmap 模块。这将以原始字节而不是 unicode 对象的形式提供数据,这可能需要在您的算法中进行更多工作(例如,对编码数据进行操作),但会使用合理数量的内存。一次将数据全部读入 Python unicode 对象将需要 2 倍或 4 倍的 RAM 占用磁盘空间(假设数据为 UTF-8)。

如果您的算法只是对数据进行一次线性传递(就像您提到的 Aho-Corasick 算法一样),那么您最好一次只读取一个合理大小的块:

with codecs.open(inpath, encoding='utf-8') as f:
    data = f.read(8192)
    while data:
        process(data)
        data = f.read(8192)

我希望这至少能让你更接近。

【讨论】:

  • 感谢您耐心的回复。我正在尝试编写对任意字母进行操作的 BLAST 算法的简化版本。 (BLAST 将您限制为 DNA、RNA 等。)第一步涉及使用 Aho-Corasick 之类的算法在大型数据库中定位查询的确切子字符串。第二步涉及在这些子字符串中搜索与整个查询相似的较长字符串(使用类似 Smith-Waterman 的算法)。 (如您所知,我对这些东西很陌生...)
  • 我选择 iPython 是因为它的并行处理能力。第二步尤其昂贵,我在 Amazon EC2 中的一台功能强大的机器上运行它。此外,当我探索这些东西时,交互环境似乎很重要......
  • 我绝对可以将我的整个数据库放入 17 GB 的内存中,但是加载时间对于测试来说太慢了。浪费这么多 EC2 时间从磁盘读取感觉像是一个错误。
  • 据我了解您的要求,您肯定想使用mmap。将您的数据转换为磁盘表示与内存表示匹配的形式,然后使用mmap 将其映射到您的地址空间。当您第一次访问数据的每个部分时,内核将需要将其读入内存一次,但是您有足够的 RAM 将保持缓存以供后续读取,即使在新进程中也是如此。回复:ipython,我不理解你所说的并行处理能力,AFAIK 就是你在 Python 中通常可以做的事情。
  • 嗯——我没有意识到 IPython 提供了它自己的多处理能力。很有趣。
【解决方案2】:

我看到你的问题中提到了 IncPy 和 IPython,所以让我插入我的一个项目,它有点朝着 IncPy 的方向发展,但可以与 IPython 一起使用并且非常适合大数据:http://packages.python.org/joblib/

如果你将数据存储在 numpy 数组中(字符串可以存储在 numpy 数组中),joblib 可以使用 memmap 来获取中间结果,并且对 IO 非常有效。

【讨论】:

  • 这看起来很棒,盖尔。谢谢。
猜你喜欢
  • 1970-01-01
  • 2015-04-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-01-22
  • 2014-09-18
  • 1970-01-01
相关资源
最近更新 更多