Python-tekenreeksklasse zoals StringBuilder in C#?

Is er een stringklasse in Python zoals StringBuilderin C#?


Antwoord 1, autoriteit 100%

Er is geen één-op-één correlatie. Voor een echt goed artikel, zie Efficiënte aaneenschakeling van strings in Python:

Lange strings bouwen in de Python
programmeertaal kan soms
resulteren in zeer traag lopende code. In
dit artikel onderzoek ik de
rekenprestaties van verschillende
tekenreeksaaneenschakelingsmethoden.

TLDR de snelste methode staat hieronder. Het is extreem compact en ook redelijk begrijpelijk:

def method6():
  return ''.join([`num` for num in xrange(loop_count)])

Antwoord 2, autoriteit 31%

Vertrouwen op compiler-optimalisaties is kwetsbaar. De benchmarks die in het geaccepteerde antwoord en de cijfers van Antoine-tran zijn gekoppeld, zijn niet te vertrouwen. Andrew Hare maakt de fout om een aanroep naar reprop te nemen in zijn methoden. Dat vertraagt alle methoden in gelijke mate, maar verdoezelt de echte straf bij het construeren van de string.

Gebruik join. Het is erg snel en robuuster.

$ ipython3
Python 3.5.1 (default, Mar  2 2016, 03:38:02) 
IPython 4.1.2 -- An enhanced Interactive Python.
In [1]: values = [str(num) for num in range(int(1e3))]
In [2]: %%timeit
   ...: ''.join(values)
   ...: 
100000 loops, best of 3: 7.37 µs per loop
In [3]: %%timeit
   ...: result = ''
   ...: for value in values:
   ...:     result += value
   ...: 
10000 loops, best of 3: 82.8 µs per loop
In [4]: import io
In [5]: %%timeit
   ...: writer = io.StringIO()
   ...: for value in values:
   ...:     writer.write(value)
   ...: writer.getvalue()
   ...: 
10000 loops, best of 3: 81.8 µs per loop

Antwoord 3, autoriteit 24%

Ik heb de code van Oliver Crow (link gegeven door Andrew Hare) gebruikt en een beetje aangepast om Python 2.7.3 aan te passen. (met behulp van timeit pakket). Ik draaide op mijn personal computer, Lenovo T61, 6GB RAM, Debian GNU/Linux 6.0.6 (squeeze).

Hier is het resultaat voor 10.000 herhalingen:

methode1: 0,0538418292999 sec
procesgrootte 4800 kb
methode2: 0.22602891922 seconden
procesgrootte 4960 kb
methode3: 0,0605459213257 seconden
procesgrootte 4980 kb
methode4: 0,0544030666351 seconden
procesgrootte 5536 kb
methode5: 0,0551080703735 seconden
procesgrootte 5272 kb
methode6: 0,0542731285095 seconden
procesgrootte 5512 kb

en voor 5.000.000 herhalingen (methode 2 werd genegeerd omdat het te langzaam liep, zoals altijd):

methode1: 5.88603997231 seconden
procesgrootte 37976 kb
methode3: 8.40748500824 seconden
procesgrootte 38024 kb
methode4: 7.96380496025 seconden
procesgrootte 321968 kb
methode5: 8.03666186333 seconden
procesgrootte 71720 kb
methode6: 6.68192911148 seconden
procesgrootte 38240 kb

Het is vrij duidelijk dat Python-jongens behoorlijk goed werk hebben geleverd om de aaneenschakeling van strings te optimaliseren, en zoals Hoare zei: “voortijdige optimalisatie is de wortel van alle kwaad” 🙂


Antwoord 4, autoriteit 20%

Python heeft verschillende dingen die vergelijkbare doelen vervullen:

  • Een veelgebruikte manier om grote snaren uit stukken te bouwen, is door een lijst met snaren te laten groeien en deze samen te voegen als je klaar bent. Dit is een veelgebruikt Python-idioom.
    • Als u strings wilt maken waarin gegevens met opmaak zijn verwerkt, moet u de opmaak afzonderlijk doen.
  • Voor invoeging en verwijdering op een tekenniveau zou u een lijst met lengte-een snaren houden. (Om dit van een string te maken, zou u list(your_string)bellen. U kunt ook een UserString.MutableStringhiervoor gebruiken.
  • (c)StringIO.StringIOis handig voor dingen die anders een bestand zouden nemen, maar minder voor algemene string-gebouw. ​​

Antwoord 5, Autoriteit 12%

Gebruikte methode 5 van boven (het pseudo-bestand) kunnen we een zeer goede PERF en flexibiliteit krijgen

from cStringIO import StringIO
class StringBuilder:
     _file_str = None
     def __init__(self):
         self._file_str = StringIO()
     def Append(self, str):
         self._file_str.write(str)
     def __str__(self):
         return self._file_str.getvalue()

Gebruik het nu

sb = StringBuilder()
sb.Append("Hello\n")
sb.Append("World")
print sb

Antwoord 6, Autoriteit 4%

U kunt stringio of CSSTRINGIO


Antwoord 7

Er is geen expliciete analoge – ik denk dat u verwacht dat u stringaconcaties gebruikt (waarschijnlijk geoptimaliseerd zoals gezegd) of klasse van derden (ik betwijfel dat ze een stuk efficiënter zijn – lijsten in Python zijn dynamisch getypt, dus Fast-working char [] voor buffer als ik aannemen).
StringBuilder-achtige klassen zijn niet voortijdige optimalisatie vanwege het aangeboren kenmerk van snaren in vele talen (immutabiliteit) – waardoor veel optimalisaties (bijvoorbeeld, verwijzen naar dezelfde buffer voor plakjes / substrings).
Stringbuilder/stringbuffer/stringstream-achtige klassen werken veel sneller dan het aaneenschakelen van strings (produceert veel kleine tijdelijke objecten die nog steeds toewijzingen en afvalverzameling nodig hebben) en zelfs printf-achtige tools voor het formatteren van tekenreeksen, zonder dat het interpreteren van opmaakpatroon-overhead nodig is die behoorlijk veel kost voor veel format-oproepen.


Antwoord 8

Als je hier op zoek bent naar een snelle methode voor het samenvoegen van strings in Python, dan heb je geen speciale StringBuilder-klasse nodig. Eenvoudige aaneenschakeling werkt net zo goed zonder de prestatievermindering die u in C# ziet.

resultString = ""
resultString += "Append 1"
resultString += "Append 2"

Zie Antinus-tran’s antwoordvoor prestatieresultaten

Other episodes