Ich habe gegoogelt und auch auf SO für den Unterschied zwischen diesen Puffermodulen suchen. Allerdings verstehe ich immer noch nicht sehr gut und ich denke, einige der Beiträge, die ich gelesen habe, sind veraltet.Verwirrend über StringIO, cStringIO und ByteIO
In Python 2.7.11 habe ich eine Binärdatei eines bestimmten Formats mit r = requests.get(url)
heruntergeladen. Dann übergab ich StringIO.StringIO(r.content)
, cStringIO.StringIO(r.content)
und io.BytesIO(r.content)
an eine Funktion zum Parsen des Inhalts.
Alle diese drei Methoden sind verfügbar. Ich meine, selbst wenn die Datei binär ist, ist es immer noch möglich, StringIO
zu verwenden. Warum?
Eine andere Sache betrifft ihre Effizienz.
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
Wie oben dargestellt, cStringIO > StringIO > BytesIO
.
Ich fand jemanden erwähnt, dass io.BytesIO
immer eine neue Kopie macht, die mehr Zeit kostet. Es gibt aber auch einige Posts, die in späteren Python-Versionen behoben wurden.
Also, kann jemand einen gründlichen Vergleich zwischen diesen IO
s, in beiden neuesten Python 2.x und 3.x machen?
Einige der Referenz ich gefunden:
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.
Aber cStringIO.StringIO('abc')
erhebt keinen Fehler
-
.
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).
- Viele SO-Posts, die hier nicht aufgeführt sind.
Es ist ein Update-Patch in diesem Beitrag in 2014.
Hier werden die Python 2.7 Ergebnisse zum Beispiel Eric sind
%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
Wie bei 2.7, cStringIO.StringIO
und StringIO.StringIO
sind wesentlich effizienter als io
.
Können Sie jedes Ihrer Sni beschriften als Python 2 oder Python 3? – Eric
@Eric, ich habe alle meine Tests in Python 2.7.11. Es scheint, dass "(c) StringIO" in 3. durch "io" ersetzt wird. Ich benutze hauptsächlich 2.7. Aber ich denke, es wäre für andere Leser sinnvoll, beide Versionen zu diskutieren. – Lee
['io'] (https://docs.python.org/2/library/io.html) ist in Python 2 ebenso – Eric