Python字符串处理优化

2024-04-29 04:54:31 发布

您现在位置:Python中文网/ 问答频道 /正文

因此,最近我编写了一个python脚本,用于从大型文本文件(大于1gb)中提取数据。这个问题基本上可以归结为从文件中选择文本行,然后从某个数组中搜索字符串(这个数组中可以有多达1000个字符串)。这里的问题是,我必须找到一个特定的字符串出现的次数,并且该字符串在该文件中出现的次数可能不受限制。此外,还需要一些解码和编码,这会进一步降低脚本的速度。 代码如下所示:

strings = [a for a in open('file.txt')]

with open("er.txt", "r") as f:
    for chunk in f:
        for s in strings
            #do search, trimming, stripping ..

我的问题是: 有什么方法可以优化这一点吗?我尝试过多处理,但它几乎没有帮助(或者至少我实现它的方式)这里的问题是这些块操作不是独立的,stringslist可能在其中一个操作期间被更改。 任何优化都会有帮助(字符串搜索算法、文件读取等),我尽可能多地进行循环中断,但它仍然运行得很慢。在


Tags: 文件数据字符串in文本txt脚本for
2条回答

如果您能够确切地知道字符串是如何以二进制(ASCII,UTF-8)编码的,那么您可以一次将整个文件^{}放入内存;它的行为与bytearray/bytes(或python2中的str)完全相同;那么这样的mmap对象可以通过str正则表达式(Python 2)或bytes来搜索正则表达式(Python3)。在

mmap是许多操作系统上最快的解决方案,因为只读映射意味着操作系统可以在页面准备就绪时自由映射;不需要交换空间,因为数据由文件支持。操作系统还可以通过零拷贝直接映射缓冲区缓存中的数据,从而实现对裸读的双赢。在

示例:

import mmap
import re

pattern = re.compile(b'the ultimate answer is ([0-9]+)')
with open("datafile.txt", "rb") as f:
    # memory-map the file, size 0 means whole file
    mm = mmap.mmap(f.fileno(), 0, prot=mmap.PROT_READ)

    # PROT_READ only on *nix as the file is not writable
    for match in pattern.finditer(mm):
        # process match
        print("The answer is {}".format(match.group(1).decode('ascii')))

    mm.close()

现在,如果datafile.txt包含文本:

^{pr2}$

在1GB数据的某个地方,这个程序将是最快的python解决方案之一:

^{3}$

请注意,^{}还接受start和{}参数,这些参数可用于限制尝试匹配的范围。在


正如ivan_pozdeev所指出的,这需要1GB的空闲虚拟地址空间来映射一个千兆字节的文件(但不一定是1GB的RAM),这在32位进程中可能很困难,但几乎可以肯定的是,在64位操作系统和CPU上“没有问题”。在32位进程上,这种方法仍然有效,但是您需要将大文件映射成更小的块—因此现在操作系统和处理器的位确实很重要。在

考虑调用一个外部进程(grep等)来加速处理并减少Python中必须处理的数据量。在

另一种方法是使用已编译的正则表达式过滤或预过滤数据,因为这样内部循环将使用标准库的优化代码。在

你也可以尝试用Cython或类似的方法来处理热的内部循环,如https://books.google.de/books?id=QSsOBQAAQBAJ&dq=high+perf+python&hl=en获取详细信息。在

相关问题 更多 >