2017-05-13 173 views
0

我想知道在我的python代码中是否有任何东西可以做,这使i/o更友好?以磁盘友好的方式将数据写入磁盘?

我知道,默认情况下,open()使用启发式确定的缓冲区,磁盘的大小为blocksize

据我所知,这只能确定数据刷新到磁盘缓存的时间。它是否正确?

我有以下情形:

我挂钩到其不断流数据的各种WebSockets的。我需要将这些数据写入磁盘。最理想的情况是,尽可能在接收和i/o动作之间尽可能少地延迟,而不要用i/o命令来谋杀我的磁盘。

我已经使用单线程来写入所有数据,而不是从各个线程(as has been pointed out here)中删除数据。但是我想知道将缓冲区设置为除default之外的其他任何内容是否合理?

我意识到负载无论如何都会令人望而生畏,但是我很好奇,是否有任何最佳实践对磁盘友好,当为这种场景编写Python代码时。

目前,我只是在做这样的:

with open(file, 'wb') as f: 
    f.write("stuff") 
+0

硬盘和操作系统的缓存/缓存是您最便宜的优化,我会说 - 你确定你在优化你的代码之前已经进行了优化? – tiwo

+0

“最理想的情况是,尽可能少的接收和I/O动作之间的延迟”听起来很软。为什么你需要快速的I/O操作? – tiwo

+2

可能相关:https://stackoverflow.com/questions/32748231/preferred-block-size-when-reading-writing-big-binary-files –

回答

2

但我不知道是否是有意义的缓冲区设置为任何东西,但这里的默认?

它可能会 - 但是您看到的任何性能改进将取决于您正在运行的系统 - 操作系统,文件系统,硬件,甚至数据在磁盘上的布局方式。因此,随着文件被创建,写入,修改和删除,您的性能甚至可能强烈依赖于文件系统使用的过去历史。将存储从单个本地5400-rpm SATA驱动器更改为带有15K-rpm SAS驱动器的RAID-6阵列的NAS系统?你的答案可能会有所不同。

唯一真正知道的方法是测试它 - 在您计划使用它的系统上。或者至少有一个相同的,你可以做到这一点。而且您需要使用您的流程实际执行的相同模式的I/O操作进行测试。如果你的I/O模式很小,从随机位置读取,那么执行大量顺序写入是没有意义的。最后,除非你在一个实际设计用于处理特定I/O模式的系统上运行,否则你可能会认为完成所有测试并不值得。

2

无论你最终与我会建议试图用“的IPython%timeit”每一种方法和比较最适合您的数据和硬件。

下面是一个分块作家的简单例子。 ASCII字符(一次一个)被加载到writeBuff中。当写入缓冲区达到1024个字符时,该块被写入磁盘。

import string 
import random 
import time 

totalLength = 2**20 
charsWritten = 0 
writeBuff = "" 

f = open("myFile.txt", "w") 
while charsWritten < totalLength: 
    writeBuff += random.choice(string.ascii_letters) 
    charsWritten += 1 
    if len(writeBuff) == 1024: 
     f.write(writeBuff) 
     writeBuff = ""  
f.write(writeBuff) 
f.close()