文件读取性能测试产生有趣的结果。可能的解释?

时间:2017-07-25 18:39:35

标签: python windows python-3.x file-io windows-7

我正在对我的系统进行压力测试,以确定文件系统可以承受多少惩罚。一个测试涉及对单个小(因此可能是高度缓存)文件的重复读取以确定开销。

以下python 3.6.0脚本生成两个结果列表:

import random, string, time

stri = bytes(''.join(random.choice(string.ascii_lowercase) for i in range(100000)), 'latin-1')

inf = open('bench.txt', 'w+b')
inf.write(stri)

for t in range(0,700,5):
    readl = b''
    start = time.perf_counter()
    for i in range(t*10):
        inf.seek(0)
        readl += inf.read(200)
    print(t/10.0, time.perf_counter()-start)

print()

for t in range(0,700,5):
    readl = b''
    start = time.perf_counter()
    for i in range(3000):
        inf.seek(0)
        readl += inf.read(t)
    print(t/10.0, time.perf_counter()-start)

inf.close()

绘制时,我得到以下图表:

Results graph

我发现这些结果非常奇怪。第二个测试(图中的蓝色,可变读取长度参数)开始线性增加,这是预期的,然后在一个点后它决定更快地爬升。更令人惊讶的是,第一次测试(粉红色,可变重复计数和固定读取长度)也显示了令人感兴趣的疯狂离开,因为读取功能的大小在那里保持固定。它也非常不规则,最好是头疼。运行测试时我的系统处于空闲状态。

在一定数量的重复之后,会出现如此严重的性能下降的合理原因是什么?

修改

readl是一个字节数组的事实显然是一个主要的性能问题。将其切换为字符串可以极大地改善一切。然而,即使使用字符串,通过比较调用读取和搜索功能也是一个次要因素。以下是测试1的更多测试变体(可变重复)。省略了测试2,因为其结果完全由字节数组性能差异完全解释:

import random, string, time

strs = ''.join(random.choice(string.ascii_lowercase) for i in range(100000))
strb = bytes(strs, 'latin-1')

inf = open('bench.txt', 'w+b')
inf.write(strb)

#bytes and read
for t in range(0,700,5):
    readl = b''
    start = time.perf_counter()
    for i in range(t*10):
        inf.seek(0)
        readl += inf.read(200)
    print(t/10.0, '%f' % (time.perf_counter()-start))
print()

#bytes no read
for t in range(0,700,5):
    readl = b''
    start = time.perf_counter()
    for i in range(t*10):
        readl += strb[0:200]
    print(t/10.0, '%f' % (time.perf_counter()-start))
print()

#string and read
for t in range(0,700,5):
    readl = ''
    start = time.perf_counter()
    for i in range(t*10):
        inf.seek(0)
        readl += inf.read(200).decode('latin-1')
    print(t/10.0, '%f' % (time.perf_counter()-start))
print()

#string no read
for t in range(0,700,5):
    readl = ''
    start = time.perf_counter()
    for i in range(t*10):
        readl += strs[0:200]
    print(t/10.0, '%f' % (time.perf_counter()-start))
print()

inf.close()

Results graph

0 个答案:

没有答案