如何使用 Python 实现最大写入速度?

Posted

技术标签:

【中文标题】如何使用 Python 实现最大写入速度?【英文标题】:How to achieve maximum write speed with Python? 【发布时间】:2016-11-17 21:44:12 【问题描述】:

我正在编写一个可以进行高速数据采集的程序。采集卡可以以高达 6.8 GB/s 的速度运行(它在 PCIe3 x8 上)。现在我正在尝试流式传输到 RAM 磁盘,以查看我可以使用 Python 实现的最大写入速度。

该卡将给我 5-10 MB 块,然后我可以在某处写入。

我写了这段代码,它将一个 10MB 的块写入一个二进制文件 500 次。我在 Windows 7 64 位上使用 Anaconda2,我使用了 Anaconda 的加速分析器。

block = 'A'*10*1024*1024
filename = "R:\\test"
f = os.open(filename, os.O_CREAT| os.O_BINARY|os.O_TRUNC|os.O_WRONLY|os.O_SEQUENTIAL)

p = profiler.Profile(signatures=False)
p.enable()
start = time.clock()
for x in range(500):
    os.write(f,block)
transferTime_sec = time.clock() - start
p.disable()
p.print_stats()

print('\nwrote %f MB' % (os.stat(filename).st_size/(1024*1024)))

我在 RAM 磁盘 (R:\) 上对此进行了测试,得到以下输出:

所以我想,我在 RAM 上获得了大约 2.5 GB/s 的速度。这还不错,但距离最大 RAM 吞吐量还很远,但数字是一致的。所以低吞吐量是一个问题。

第二个问题是,当我使用 PCIe SSD 测试此代码时(我曾用另一个软件以 1090 MB/s 的顺序写入速度对其进行基准测试),它给出了可比较的数字。

这让我觉得它在缓存和/或缓冲(?),所以我只是没有测量​​实际的 IO。我不确定到底发生了什么,因为我对 python 还很陌生。

所以我的主要问题是如何实现最大写入速度,而另一个问题是为什么我会得到这些数字?

【问题讨论】:

我想知道,你为什么用os.open() 而不是open() ?? 男性确定没有进程正在拦截写入,是的,我正在看着你的 windows 防御者。 @ShadyAtef 对文件属性的更多控制,可能是直接 IO @MostafaAbdelraouf 不,不是这样 我有一个建议,但我觉得会有点难。尝试在不同的操作系统上进行基准测试。使用 Windows 性能工具或其他工具(我不是这方面的专家)来跟踪您对设备和内存的写入.. 【参考方案1】:

我不知道你是否还在关注这个问题,但我发现你的问题很有趣,所以我在 Linux 笔记本电脑上试了一下。

我在 python 3.5 上运行了您的代码,发现您还需要有 os.O_SYNC 标志以避免缓冲问题(基本上,在所有数据都写入磁盘之前,os.write 函数不会返回)。我还将time.clock() 替换为time.time(),这会给我带来更好的结果。

import os
import time
import cProfile

def ioTest():
    block = bytes('A'*10*1024*1024, 'utf-8')
    filename = 'test.bin'
    f = os.open(filename, os.O_WRONLY | os.O_CREAT | os.O_TRUNC |
                os.O_SYNC)
    start = time.time()
    for x in range(500):
        os.write(f,block)
    os.close(f)
    transferTime_sec = time.time() - start
    msg = 'Wrote :0fMB in :0.03fs'
    print(msg.format(os.stat(filename).st_size/1024/1024,
                     transferTime_sec))
cProfile.run('ioTest()')

另外,这个post 谈论使用os.O_DIRECT 标志,它将使用DMA 并避免瓶颈。我不得不使用 mmap 模块让它在我的机器上工作:

import os
import time
import cProfile
import mmap

def ioTest():
    m = mmap.mmap(-1, 10*1024*1024)
    block = bytes('A'*10*1024*1024, 'utf-8')
    m.write(block) filename = 'test.bin'
    f = os.open(filename, os.O_WRONLY | os.O_CREAT | os.O_TRUNC |
                os.O_SYNC, os.O_DIRECT)
    start = time.time()
    for x in range(500):
        os.write(f,m)
    os.close(f)
    transferTime_sec = time.time() - start
    msg = 'Wrote :0fMB in :0.03fs.'
    print(msg.format(os.stat(filename).st_size/1024/1024,
                     transferTime_sec))
cProfile.run('ioTest()')

这将我机器上的写入时间减少了 40%……还不错。 我没有使用我的机器上不可用的os.O_SEQUENTIALos.O_BINARY

[编辑]:我从site 中找到了如何使用 os.O_DIRECT 标志,它很好地深入地解释了它。如果您对 Python 中的性能和直接 IO 感兴趣,我强烈建议您阅读这篇文章。

【讨论】:

以上是关于如何使用 Python 实现最大写入速度?的主要内容,如果未能解决你的问题,请参考以下文章

Uber是如何通过Mesos和Cassandra实现跨多个数据中心每秒100万的写入速度的?

python向nas上写入数据很慢

如何通过python复制xlsx,rar等格式的文件到剪贴板中?

Python:使用多处理池时使用队列写入单个文件

sql 如何向数据库中写入的速度快

如何使用日志记录 Python 模块写入文件?