python - ¿Cuándo se usa StringIO, a diferencia de unirse a una lista de cadenas?
stringio python 3 (4)
Usar StringIO como un buffer de cadena es más lento que usar list como buffer.
¿Cuándo se usa StringIO?
from io import StringIO
def meth1(string):
a = []
for i in range(100):
a.append(string)
return ''''.join(a)
def meth2(string):
a = StringIO()
for i in range(100):
a.write(string)
return a.getvalue()
if __name__ == ''__main__'':
from timeit import Timer
string = "This is test string"
print(Timer("meth1(string)", "from __main__ import meth1, string").timeit())
print(Timer("meth2(string)", "from __main__ import meth2, string").timeit())
Resultados:
16.7872819901
18.7160351276
Bueno, no sé si me gustaría llamarlo usándolo como un "buffer", solo estás multiplicando una cadena 100 veces, en dos formas complicadas. Aquí hay una forma sencilla:
def meth3(string):
return string * 100
Si lo agregamos a su prueba:
if __name__ == ''__main__'':
from timeit import Timer
string = "This is test string"
# Make sure it all does the same:
assert(meth1(string) == meth3(string))
assert(meth2(string) == meth3(string))
print(Timer("meth1(string)", "from __main__ import meth1, string").timeit())
print(Timer("meth2(string)", "from __main__ import meth2, string").timeit())
print(Timer("meth3(string)", "from __main__ import meth3, string").timeit())
Resulta ser mucho más rápido como una bonificación:
21.0300650597
22.4869811535
0.811429977417
Si desea crear un conjunto de cadenas y luego unirlas, meth1 () es la forma correcta. No tiene sentido escribirlo en StringIO, que es algo completamente diferente, a saber, una cadena con una interfaz de flujo similar a un archivo.
La principal ventaja de StringIO es que puede usarse donde se esperaba un archivo. Para que pueda hacer, por ejemplo (para Python 2):
import sys
import StringIO
out = StringIO.StringIO()
sys.stdout = out
print "hi, I''m going out"
sys.stdout = sys.__stdout__
print out.getvalue()
Otro enfoque basado en el enfoque de Lennart Regebro. Esto es más rápido que el método de lista (meth1)
def meth4(string):
a = StringIO(string * 100)
contents = a.getvalue()
a.close()
return contents
if __name__ == ''__main__'':
from timeit import Timer
string = "This is test string"
print(Timer("meth1(string)", "from __main__ import meth1, string").timeit())
print(Timer("meth2(string)", "from __main__ import meth2, string").timeit())
print(Timer("meth3(string)", "from __main__ import meth3, string").timeit())
print(Timer("meth4(string)", "from __main__ import meth4, string").timeit())
Resultados (seg.):
meth1 = 7.731315963647944
meth2 = 9.609279402186985
meth3 = 0.26534052061106195
meth4 = 2.915035489152274
Si mide la velocidad, debe usar cStringIO
.
De los docs :
El módulo cStringIO proporciona una interfaz similar a la del módulo StringIO. El uso intensivo de los objetos StringIO.StringIO se puede hacer más eficiente si se utiliza la función StringIO () de este módulo.
Pero el objetivo de StringIO es ser un objeto similar a un archivo , para cuando algo lo espere y no desee usar archivos reales.
Editar: me di cuenta de que utiliza from io import StringIO
, por lo que probablemente esté en Python> = 3 o al menos 2.6. El StringIO y cStringIO por separado se han ido en Py3. No estoy seguro de qué implementación utilizaron para proporcionar el io.StringIO. Hay io.BytesIO
también.