【问题标题】:what's the more effecient way to read a text file读取文本文件的更有效方法是什么
【发布时间】:2013-08-18 08:57:26
【问题描述】:

有文本文件(约300M),需要统计前N个频率词。第一步是从磁盘读取它,现在我只是使用open.read().lower()(不区分大小写)有没有更有效的方式来处理IO部分?测试机8核4G内存,Linux系统,python版本为2.6。

【问题讨论】:

  • 您需要多快?您可以获得一个基线,它很好地考虑了 IO 和单词拆分time wc -w m30text.txt → 0.67 秒挂钟。 Martijn 对同一个 30M 字(磁盘上 34MB)文本文件的回答:3.0s。 Python GIL 可能会阻止您减少 2.3 秒来填充 Counter 对象,无论您有多少内核。
  • 谢谢,也许 python 不是解决这类问题的合适语言
  • 这根本不是预期的结论。您对文件被读取和解析成单词的速度有一个下限。如果您测量了正确、无错误且性能更高的替代实现,请向我们展示。在你测量它之前,它并不存在,而且大多数人对 Python 内在函数性能的直觉通常是不正确的。
  • @msw 我的测试文件大约20M,最好的java时间大约是350ms,最好的C++时间大约是170ms。

标签: python performance io


【解决方案1】:

是的,在迭代器中逐行处理文件:

with open(filename) as inputfile:
    for line in inputfile:
        line = line.lower()

这使用缓冲区来提高读取性能,但不会对您的内存造成太大压力,从而避免了交换。

接下来,使用collections.Counter() 为您进行频率计数。它将以纯 Python 代码中最有效的方式为您处理计数和选择前 N 个单词。

获取单词的一种天真的方法是在空格上分割行;将它与生成器表达式相结合可以在一行代码中为您提供所有字数:

from collections import Counter

with open(filename) as inputfile:
    counts = Counter(word for line in inputfile for word in line.lower().split())

for word, frequency in counts.most_common(N):
    print '{<40} {}'.format(word, frequency)

Counter 类是在 Python 2.7 中添加的;对于 2.6,您可以使用 this backport

【讨论】:

  • 谢谢,只有当内存无法加载所有数据时,逐行读取才有意义? Counter() 是否使用多线程模块来完成频率字数统计工作?
  • 不,Counter() 不使用任何多进程或线程技巧。你必须自己做,然后重新组合结果。 Counter() 对象可以很容易地求和。
  • Counter() 比我以前用的堆快,我试试多进程,谢谢
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-12-23
  • 1970-01-01
  • 1970-01-01
  • 2014-04-15
  • 1970-01-01
  • 2014-02-01
相关资源
最近更新 更多