L'utilisation de StringIO comme tampon de chaîne est plus lente que l'utilisation de list comme tampon.
Quand StringIO est-il utilisé?
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 __== '__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())
Résultats:
16.7872819901
18.7160351276
Si vous mesurez la vitesse, vous devez utiliser cStringIO
.
De la docs :
Le module cStringIO fournit une interface similaire à celle du module StringIO. Une utilisation intensive des objets StringIO.StringIO peut être rendue plus efficace en utilisant à la place la fonction StringIO () de ce module.
Mais le but de StringIO est d'être un objet semblable à un fichier, lorsque quelque chose l'attend et que vous ne voulez pas utiliser de fichiers réels.
Edit: J'ai remarqué que vous utilisez from io import StringIO
, vous êtes donc probablement sur Python> = 3 ou au moins 2.6. Les StringIO et cStringIO séparés ont disparu dans Py3. Vous ne savez pas quelle implémentation ils ont utilisée pour fournir l'io.StringIO. est io.BytesIO
aussi.
Le principal avantage de StringIO est qu'il peut être utilisé là où un fichier était attendu. Vous pouvez donc faire par exemple (pour 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()
Eh bien, je ne sais pas si je voudrais appeler cela en l'utilisant comme "tampon", vous multipliez simplement une chaîne 100 fois, de deux manières compliquées. Voici une manière simple:
def meth3(string):
return string * 100
Si nous ajoutons cela à votre test:
if __== '__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())
Il s'avère être beaucoup plus rapide en bonus:
21.0300650597
22.4869811535
0.811429977417
Si vous souhaitez créer un tas de chaînes, puis les joindre, meth1 () est la bonne façon. Il est inutile de l'écrire dans StringIO, ce qui est complètement différent, à savoir une chaîne avec une interface de flux de type fichier.