У меня есть googled, а также поиск по SO для разницы между этими буферными модулями. Тем не менее, я все еще не очень хорошо понимаю, и я думаю, что некоторые из прочитанных мной постов устарели.Смущение о StringIO, cStringIO и ByteIO
В Python 2.7.11 я загрузил двоичный файл определенного формата, используя r = requests.get(url)
. Затем я передал StringIO.StringIO(r.content)
, cStringIO.StringIO(r.content)
и io.BytesIO(r.content)
функции, предназначенной для синтаксического анализа содержимого.
Все эти три метода доступны. Я имею в виду, что даже если файл двоичный, все же можно использовать StringIO
. Зачем?
Другое дело об их эффективности.
In [1]: import StringIO, cStringIO, io
In [2]: from numpy import random
In [3]: x = random.random(1000000)
In [4]: %timeit y = cStringIO.StringIO(x)
1000000 loops, best of 3: 736 ns per loop
In [5]: %timeit y = StringIO.StringIO(x)
1000 loops, best of 3: 283 µs per loop
In [6]: %timeit y = io.BytesIO(x)
1000 loops, best of 3: 1.26 ms per loop
Как показано выше, cStringIO > StringIO > BytesIO
.
Я нашел, что кто-то упомянул, что io.BytesIO
всегда делает новую копию, которая стоит больше времени. Но есть также упоминания о том, что это было исправлено в более поздних версиях Python.
Итак, может ли кто-нибудь провести тщательное сравнение между этими IO
s, как в последних версиях Python 2.x, так и 3.x?
Некоторые ссылки я нашел:
- https://trac.edgewall.org/ticket/12046
io.StringIO requires a unicode string. io.BytesIO requires a bytes string. StringIO.StringIO allows either unicode or bytes string. cStringIO.StringIO requires a string that is encoded as a bytes string.
Но cStringIO.StringIO('abc')
не вызывает каких-либо ошибок.
https://review.openstack.org/#/c/286926/1
The StringIO class is the wrong class to use for this, especially considering that subunit v2 is binary and not a string.
http://comments.gmane.org/gmane.comp.python.devel/148717
cStringIO.StringIO(b'data') didn't copy the data while io.BytesIO(b'data') makes a copy (even if the data is not modified later).
Существует исправление патч на этом посту в 2014 г.
- Много сообщений SO, не перечисленных здесь.
Вот Python 2.7 Результаты, например Эрика
%timeit cStringIO.StringIO(u_data)
1000000 loops, best of 3: 488 ns per loop
%timeit cStringIO.StringIO(b_data)
1000000 loops, best of 3: 448 ns per loop
%timeit StringIO.StringIO(u_data)
1000000 loops, best of 3: 1.15 µs per loop
%timeit StringIO.StringIO(b_data)
1000000 loops, best of 3: 1.19 µs per loop
%timeit io.StringIO(u_data)
1000 loops, best of 3: 304 µs per loop
# %timeit io.StringIO(b_data)
# error
# %timeit io.BytesIO(u_data)
# error
%timeit io.BytesIO(b_data)
10000 loops, best of 3: 77.5 µs per loop
Что касается 2.7, cStringIO.StringIO
и StringIO.StringIO
являются гораздо более эффективными, чем io
.
Можете ли вы пометить каждый из ваших sni ppets как python 2 или python 3? – Eric
@ Эрик, я сделал все свои тесты в Python 2.7.11. Кажется '(c) StringIO' заменяется на' io' в 3. Я в основном использую 2.7. Но я думаю, что для других читателей было бы целесообразно обсудить обе версии. – Lee
['io'] (https://docs.python.org/2/library/io.html) также находится в python 2 – Eric