我正在尝试对我的硬盘进行基准测试,也就是说计算它的延迟(ms)和吞吐量(MB/s)。为此,我想测量Python的函数f.write的执行时间。我需要的是在我的文件中写入x个字节。我知道我需要使用打开我的文件
f = open(file_name, 'wb')
然后我做的是
for i in range(blocksize)
f.write(b'xff')
然而,我获得的吞吐量(MB/s)结果太低了。延迟看起来是正确的。因此,我推断出,当我执行前几行时,我实际上正在向文件中写入多个字节,我正在写入一个包含一个字节的字符串。。。我知道这个对象在Python中并没有真正的大小,但有办法解决这个问题吗?
编辑好吧,这是新的代码,现在的结果太高了!我的磁盘写入限制应该是100MB/s,但我的结果快了十倍。怎么了?导入系统导入时间
f = open("test.txt",'wb+')
def file_write_seq_access(blocksize):
chunk = b'xff'*4000
for i in range(blocksize//4000):
f.write(chunk)
if __name__ == '__main__':
start_time = time.time()
file_write_seq_access(int(sys.argv[1]))
stop_time = time.time()
diff = stop_time - start_time
print diff, "s"
print (int(sys.argv[1])/diff),"B/s"
简单地说,Python对于这种逐字节写入来说不够快,并且文件缓冲和类似的操作增加了太多的开销。
你应该做的是大块操作:
import sys
blocksize = int(sys.argv[1])
chunk = b'xff'*10000
with open("file.file", "wb") as f:
for _ in range(blocksize // 10000):
f.write(chunk)
可能使用PyPy
应该会进一步(非常小,可能是负的)加速。
请注意,操作系统会干扰这里的计时,因此会有很多的差异。使用C可能会更快。
经过一些计时后,这与dd
的速度相匹配,所以你不会变得更快。
要使结果良好,需要使用低级别I/O来最大限度地减少调用时间开销并刷新缓冲区,否则您的写入可能会在某个地方缓冲(例如,您使用的操作系统)。
from time import perf_counter as time
def write_test(file, block_size, blocks_count):
f = os.open(file, os.O_CREAT|os.O_WRONLY, 0o777) # low-level I/O
took = []
for i in range(blocks_count):
buff = os.urandom(block_size) # get random bytes
start = time()
os.write(f, buff)
os.fsync(f) # force write to disk
t = time() - start
took.append(t)
os.close(f)
return took
这段代码是我业余项目的一部分——Python中一个简单的工具,用于对HDD和SSD进行基准测试。它是完全开源的,现在处于alpha阶段,尽管你已经可以使用它了,如果感兴趣的话,可以参与开发。希望你能找到一些好的想法,甚至提供你的想法。链接如下:https://github.com/thodnev/MonkeyTest