【问题标题】:Python - Benchmarking Disk - Write exactly x bytes in a filePython - 基准磁盘 - 在文件中准确写入 x 个字节
【发布时间】:2014-11-14 15:27:39
【问题描述】:

我正在尝试对我的硬盘进行基准测试,即计算其延迟 (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 file byte benchmarking disk


    【解决方案1】:

    简单地说,对于这种逐字节写入,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 的速度相匹配,因此您不会变得更快。

    【讨论】:

    • 你用什么来计时? time.time() ?
    • 如果你知道的话,你可能想让你的卡盘大小等于文件系统块的大小。如果您不确定有多大,4kb 通常是一个不错的猜测。
    • 我在虚拟机中运行 linux,那么文件系统块大小是 windows 的一个还是 linux 的一个?您认为在 VM 中运行会对我的计时准确性产生副作用吗?
    • @JahMyst time python3/python2/pypy/pypy3 wite_blocks.py 100000000.
    • 请看编辑后的代码,现在我的结果太高了,我不明白为什么。我用 time.time() 计时。与 timeit 模块的结果相同 ...
    【解决方案2】:

    您需要使结果良好的是使用低级 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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-03-05
      • 2017-09-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-05-02
      • 1970-01-01
      相关资源
      最近更新 更多