StringIO的代码中有以下注释:
Notes:
- Using a real file is often faster (but less convenient).
- There's also a much faster implementation in C, called cStringIO, but
it's not subclassable.“真正的文件往往更快”这句话对我来说真的很奇怪:怎么能写到磁盘,快写到内存呢?我试着分析了这些不同的案例,得到了与这些文档相矛盾的结果以及这个问题的答案。另一个问题确实解释了为什么在某些情况下cStringIO比较慢,尽管我在这里没有做任何连接。测试将给定数量的数据写入文件,然后查找开始并将其读回。在“新”测试中,我每次都创建一个新的对象,而在“相同的”测试上,每次重复都会截断和重用相同的对象,以排除开销的来源。这种开销对于使用具有小数据大小但不太大的文件很重要。
代码是这里。
Using 1000 passes with size 1.0KiB
New StringIO: 0.0026 0.0025 0.0034
Same StringIO: 0.0026 0.0023 0.0030
New cStringIO: 0.0009 0.0010 0.0008
Same cStringIO: 0.0009 0.0009 0.0009
New tempfile: 0.0679 0.0554 0.0542
Same tempfile: 0.0069 0.0064 0.0070
==============================================================
Using 1000 passes with size 100.0KiB
New StringIO: 0.0093 0.0099 0.0108
Same StringIO: 0.0109 0.0090 0.0086
New cStringIO: 0.0130 0.0139 0.0120
Same cStringIO: 0.0118 0.0115 0.0124
New tempfile: 0.1006 0.0905 0.0899
Same tempfile: 0.0573 0.0526 0.0523
==============================================================
Using 1000 passes with size 1.0MiB
New StringIO: 0.0727 0.0700 0.0717
Same StringIO: 0.0740 0.0735 0.0712
New cStringIO: 0.1484 0.1399 0.1470
Same cStringIO: 0.1493 0.1393 0.1465
New tempfile: 0.6576 0.6750 0.6821
Same tempfile: 0.5951 0.5870 0.5678
==============================================================
Using 1000 passes with size 10.0MiB
New StringIO: 1.0965 1.1129 1.1079
Same StringIO: 1.1206 1.2979 1.1932
New cStringIO: 2.2532 2.2162 2.2482
Same cStringIO: 2.2624 2.2225 2.2377
New tempfile: 6.8350 6.7924 6.8481
Same tempfile: 6.8424 7.8114 7.8404
==============================================================这两种StringIO实现具有相当的可比性,尽管对于较大的数据大小,cStringIO的实现速度明显减慢。但tempfile.TemporaryFile所用的时间总是比最慢的StringIO长3倍。
发布于 2016-02-03 19:27:03
这完全取决于“经常”是什么意思。StringIO是通过在列表中保持写入,然后在读取时将列表加入到字符串来实现的。您的测试用例--一系列的写,然后是读--是它最好的场景。如果我将测试用例调整为对文件进行50次随机写入/读取,那么cStringIO就会以文件系统的第二名获胜。
这个评论似乎反映了系统程序员的偏见,即让c库加上操作系统做文件系统的事情,因为在一般意义上很难猜测什么在所有条件下表现最好。
def write_and_read_test_data(flo):
fsize = len(closure['test_data'])
flo.write(closure['test_data'])
for _ in range(50):
flo.seek(random.randint(0, fsize-1))
flo.write('x')
flo.read(1)
flo.seek(0)
closure['output'] = flo.read()10 my测试用例花费的时间超过了我的注意力.
Using 1000 passes with size 1.0KiB
New StringIO: 0.9551 0.9467 0.9366
Same StringIO: 0.9252 0.9228 0.9207
New cStringIO: 0.3274 0.3280 0.3251
Same cStringIO: 0.3182 0.3231 0.3280
New tempfile: 1.1833 1.1853 1.1650
Same tempfile: 0.9563 0.9414 0.9504
==============================================================
Using 1000 passes with size 100.0KiB
New StringIO: 5.6253 5.6589 5.6025
Same StringIO: 5.5799 5.5608 5.5589
New cStringIO: 0.4157 0.4133 0.4140
Same cStringIO: 0.4078 0.4076 0.4088
New tempfile: 2.0420 2.0391 2.0408
Same tempfile: 1.5722 1.5749 1.5693
==============================================================
Using 1000 passes with size 1.0MiB
New StringIO: 105.2350 106.3904 107.5411
Same StringIO: 108.3744 109.4510 105.6012
New cStringIO: 2.4698 2.4781 2.4165
Same cStringIO: 2.4699 2.4600 2.4451
New tempfile: 6.6086 6.5783 6.5916
Same tempfile: 6.1420 6.1614 6.1366https://stackoverflow.com/questions/35185020
复制相似问题