python读取/迭代文件的速度是pypypy的两倍

2024-04-25 23:08:55 发布

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

通常,对于常规的简单python代码,使用pypy会更快。但为什么当我读取一个文件,仅仅拆分字符串并执行非常简单的逻辑时,它比普通python慢得多

请参考以下代码

首先,让我们使用以下代码创建一个假文件:

NUM_ROWS = 10000000
FILENAME = "testing.txt"

def create_file():
    data = []
    for x in range(NUM_ROWS):
        data.append("AA BB CC DD EE FF GG HH II JJ KK LL MM NN OO\n")

    with open(FILENAME, "w") as f:
        for d in data:
            f.write(d)
        f.close()

这只是创建了一个名为testing.txt的文件

然后我们有一个sample.py

import datetime
FILENAME = "testing.txt"

start = datetime.datetime.now()
with open(FILENAME) as f:
    for i, line in enumerate(f):
        data = line.split(" ")
        if data[0] != "AA":
            print(i, line)
print(datetime.datetime.now() - start)

C:\pypy3.6-v7.3.1-win32\pypy3.exe sample.py需要42s,而python sample.py只需要18s

我正在windows 10计算机上使用python3.7。有没有一种方法可以使用pypy来加速上面这样一个简单的脚本?我用错了吗

------更新:

显然,pypy中的“读取”或迭代文件速度很慢

将sample.py设置为:

import datetime
FILENAME = "testing.txt"

start = datetime.datetime.now()
with open(FILENAME, "r") as f:
    for line in f:
        pass
print(datetime.datetime.now() - start)

我尝试了20200818的最新Py3版本。下面是我关于上面简单代码的发现(只是简单地逐行迭代一个1000万行的文件)。在Windows中,常规python(3.8)执行上述代码需要2.3秒,而使用pypy3则需要非常慢的30秒。在Ubuntu中,普通python需要1.2秒,Py3需要3.4秒。linux版本肯定更容易接受,但windows肯定需要做一些工作

有没有办法用pypy for windows加速文件的读取/迭代


Tags: 文件sample代码inpytxtfordata
1条回答
网友
1楼 · 发布于 2024-04-25 23:08:55

问题已更新,因此我更新了我的答案:

与每次优化一样,您需要对每个零件进行轮廓分析。 当然,您应该关注循环中的命令

我通过相同测试的解决方案(无需分析)是:

import datetime
FILENAME = "testing.txt"

start = datetime.datetime.now()
with open(FILENAME) as f:
    i = 0
    data = f.readline()
    while data:
        if not data.startswith('AA '):
            print(i, line)
        i += 1
        data = f.readline()

print(datetime.datetime.now() - start)


然而,这并不是@user1179317所期望的解决方案 在更新的问题中@user1179317现在意识到读取文件数据块是一个问题

您可以尝试使用yield分块读取数据:

def read_in_chunks(file_object, chunk_size=1024):
    """generator to read file in chunks"""
    while True:
        data = file_object.read(chunk_size)
        if not data:
            break
        yield data


with open('big_file.data') as f:
    for piece in read_in_chunks(f):
        process_data(piece)

另一种选择是使用iter和辅助功能:

f = open('big_file.dat')
def read_chunk(chunk_size=1024):
    return f.read(chunk_size)

for piece in iter(read_chunk, ''):
    process_data(piece)

同样-这不是一个ready to use past & copy答案-您需要分析和测试,因为结果将取决于文件大小、可用ram、硬盘的块大小、IP数据包大小等

由于该操作是I/O绑定的,所以多线程方法可能是好的——您可以尝试在单独的线程中读取文件的下一个块

因此,您需要使用不同的块大小进行配置

相关问题 更多 >