【问题标题】:How to accomplish this task faster writing code with some hacks?如何通过一些技巧更快地完成这项任务?
【发布时间】:2018-09-06 15:06:47
【问题描述】:

我有一个包含大约 1.3 亿字的大型文本文件用于测试目的。为了计算文件中的单词,我编写了以下代码,我称之为“普通解决方案”。

#!/usr/bin/python3.7

with open('v_i_m_utf8.txt') as infile:
    words=0
    for line in infile:
        wordslist = line.split()
        words += len(wordslist)
print(words)

我现在得到的结果:

tony@lenox:~$ time ./counting.py

 134721552

 real   0m29,391s

 user   0m28,907s

 sys    0m0,400s

 tony@lenox:~$ 

请问,是否可以使用一些 python 内部技巧来更快地处理字符串?

我只需要数单词并尽可能快地完成 Python 运行时。

【问题讨论】:

  • 没有用python,你试过wc -w v_i_m_utf8.txt吗?这是一个成熟的专门编写的程序,可能是用 C 语言编写的。
  • 谢谢,但我很想在 Python 中仅针对这种情况搜索解决方案,没有标准的 unix utils
  • @cdarke 在我的硬件上的执行时间tony@lenox:~$ time wc -w v_i_m_utf8.txt 134721552 v_i_m_utf8.txt real 0m55,585s user 0m54,192s sys 0m0,552s
  • @cdarke, $ time wc -w v_i_m.utf 134721552 v_i_m.utf wc -w v_i_m.utf 33.26s user 0.18s system 99% cpu 33.461 total from PC with better performance that mine.跨度>

标签: python string python-3.x performance


【解决方案1】:

Cython 算不算?

cdef extern from "ctype.h":
    int isspace(int x)

def cfunc(fd):
  cdef bytes buf
  cdef int tot = 0, prev = 0, cur
  cdef char c
  while True:
      buf = fd.read(8192)
      if not buf:
        return tot
      for c in buf:
        cur = isspace(c)
        if cur and not prev:
          tot += 1
        prev = cur

我电脑上的时间是:

  • OP 的例子耗时 6.5s
  • George 耗时 5.3 秒
  • 此 Cython 代码需要 0.65 秒
  • 类似的 C 版本需要 0.73s(不知道为什么比 Cython 长)

    gcc -mtune=native -march=native -Wall -O3编译

【讨论】:

  • 是的,当然是 cout。请给我你的程序的完整列表,以便用 Cython 编译它。
  • 但感谢您的帮助,请向我展示您的解决方案使用的简短示例
  • #!/usr/bin/python3 from cfunc import cfunc with open('v_i_m_utf8.txt', 'rb') as infile: words = 0 words = cfunc(infile) print(words) 我想这是正确的。
  • 我倾向于在 Jupyter 笔记本上玩,它对 Cython 有很好的支持......你的例子是正确的,不需要初始化 words=0 因为你立即将它设置为其他东西,但是你'基本明白了
【解决方案2】:

读取整个文件而不是逐行读取。

words = len(infile.read().split())

【讨论】:

  • 感谢您的回答,但该示例在我的 Lenovo G580(Intel Core i3 2370M 和 8Gb RAM)上运行时被 OOM 杀手杀死:-(文件大小约为 1.6Gb utf8 编码的俄罗斯文本。我来自 OP 的代码吃掉了这么多数据,没有任何内存消耗问题......
  • 您可以将参数传递给read 以限制读取的字节数。读取和处理块,直到文件完成并像原始文件一样对长度求和。
猜你喜欢
  • 1970-01-01
  • 2021-06-30
  • 2020-09-18
  • 2023-03-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-04-05
相关资源
最近更新 更多