Laden...

Performance String/StringBuilder

Erstellt von Cookiie vor 16 Jahren Letzter Beitrag vor 16 Jahren 2.233 Views
Cookiie Themenstarter:in
363 Beiträge seit 2007
vor 16 Jahren
Performance String/StringBuilder

Hi Leute,

ich hab mir als Grundlektüre schon das entsprechende Kapitel im OpenBook durchgelesen. Habe aber noch eine Frage, die mir das Buch so nicht beantworten konnte.

Folgende Situation:
Ich erzeuge mir den String neu, was ist besser
Fall 1:

string str = "lala" + var1 + "bubu" + var2 + "knoblauch";

Fall 2:

string str = new string("lala" + var1 + "bubu" + var2 + "knoblauch");

Fall 3


StringBuilder strb = new StringBuilder();
strb.Append("lala");
strb.Append(var1);
strb.Append("bubu");
strb.Append(var2);
strb.Append("knoblauch");
string str = strb.toString();

Oder macht das am Ende gar keinen Unterschied?. Die Frage ist halt, ob dieser Art der Erzeugung die einzelnen Komponenten schon Objekte sind, oder der neue String das einzige Objekt ist.

Erleuchtet mich
Cookiie

"Hail to the King, Baby!"

343 Beiträge seit 2007
vor 16 Jahren

Hallo Cookiie!

Also Fall 1 und 2 sind gleichwertig was die Geschwindigkeit anbelangt. (edit: Davon abgesehen, dass Fall 2 vom Compiler nicht zugelassen wird. 😄)
Fall 3 dürfte nach meiner Erfahrung sich NICHT auszahlen. Könnte man eigentlich ganz einfach ein Testprogramm machen und prüfen was länger dauert.
Hab auch mal viel Zeit in String Optimierung gesteckt und habe danach festgestellt, dass es sich in vielen Fällen NICHT auszahlt auf StringBuilder zu wechseln. (Außer natürlich wenn sehr, sehr viel verändert wird und der String selten ausgelesen wird)

Mfg Preli

//edit: Hab jetzt mal ein Testprogramm geschrieben (war selbst neugierig). Fall 1 ist ca. 30 Prozent schneller. Selbst in diesem Fall
Fall1:

string str = "lala" + var1 + "bubu" + var2 + "knoblauch" + "lala" + var1 + "bubu" + var2 + "knoblauch" + "lala" + var1 + "bubu" + var2 + "knoblauch" + "lala" + var1 + "bubu" + var2 + "knoblauch";

Fall3:

StringBuilder strb = new StringBuilder();
                strb.Append("lala");
                strb.Append(var1);
                strb.Append("bubu");
                strb.Append(var2);
                strb.Append("knoblauch");
                strb.Append("lala");
                strb.Append(var1);
                strb.Append("bubu");
                strb.Append(var2);
                strb.Append("knoblauch");
                strb.Append("lala");
                strb.Append(var1);
                strb.Append("bubu");
                strb.Append(var2);
                strb.Append("knoblauch");
                strb.Append("lala");
                strb.Append(var1);
                strb.Append("bubu");
                strb.Append(var2);
                strb.Append("knoblauch");
                str = strb.ToString();

Es gab schon mal so einen ähnlichen Thread (siehe hier Arbeiten mit strings beschleunigen ). Dort stelle ich ganz unten auch eine eigene Klasse von mir vor (StringBuilder), die in manchen Fällen sogar schneller als string sein kann.
Schau's dir mal an (am besten auch die Excel-Datei)

[- www.saftware.net -](http://www.saftware.net/)
Cookiie Themenstarter:in
363 Beiträge seit 2007
vor 16 Jahren

Ok Fall 2 hab ich ned getestet ^^.
Mir ging es halt hauptsächlich darum, ob der Unterschied schon beim Erzeugen zum tragen kommt oder vernachlässigbar ist.
Bei nachträglichen Ändern des Strings ist es klar das man da lieber Stringbuilder verwendet, erst recht wenn es öfters geschieht.
Aber gut zu wissen, das ich jetzt mein Programm nicht zwangsoptimieren muss 🙂

Danke
Cookiie

Edith:
thx, fürs testen ist für mich auf alle Fälle mehr als ausreichend
zu deiner Stringbuffer-Klasse, sehr interessant, aber das wäre in meinem Fall mit Kanonen auf Spatzen geschossen

"Hail to the King, Baby!"

343 Beiträge seit 2007
vor 16 Jahren

Original von Cookiie
Aber gut zu wissen, das ich jetzt mein Programm nicht zwangsoptimieren muss 🙂

Hatte auch mal ein Programm mit vielen Stringoperationen, das ich dann optimiert habe. Also von String auf StringBuilder. Hat mich ca. 20 Stunden Arbeit gekostet um danach festzustellen, dass es ungefähr gleich schnell war wie zuvor.

Mfg Preli

[- www.saftware.net -](http://www.saftware.net/)
Cookiie Themenstarter:in
363 Beiträge seit 2007
vor 16 Jahren

Da fällt mir nur ein Zitat zu ein, was ich gestern erst wieder lesen musste.

"Wenns läuft, repariers nicht." 🙂

"Hail to the King, Baby!"

F
10.010 Beiträge seit 2004
vor 16 Jahren

Es ist in der heutigen Zeit, bei den Compilern sowieso schlecht, gleich auf
jeden "Trick" zur optimierung zu gehen.

Lieber Verständlichen code schreiben, der Wartbar bleibt, und ggf mit einem
Profiler schauen, wo wirklich die Zeit drauf geht.

http://www.softprodigy.com/profilesharp/Index.aspx

Cookiie Themenstarter:in
363 Beiträge seit 2007
vor 16 Jahren

Ach das Hauptzeit/Performance-Problem weiß ich ja. .NET 1.1 und seine Handhabung von Threadaufruf und Parametern.
Das geht bei .net 2.0 wesentlich besser und performanter.

Gruß Cookiie

"Hail to the King, Baby!"

0
767 Beiträge seit 2005
vor 16 Jahren

wenn man die strings direkt hintereinander hängen kann, wie bei deinem beispiel 1 ist immer der + operator der schnellste. egal wie viele du aneinander hängst.

wenn du strings in einer schleife aufbaust, und bei jedem durchlauf was dazuhängst, ist der StringBuilder zu empfehlen aber auch erst ab minstens 20 durchläufen.

der grund, dass der + operator im ersten fall schneller ist ist der folgende:
der compiler macht draus ein


string.Concat(s1,s2,s3,s4...)

dadurch kann das .net framework zuerst berechnen wie lang der result string in summe sein wird, den speicher einmalig anlegen und dann die strings in den speicher schreiben.

der stringbuilder würde mitwachsen was aber dazu führt, dass jedesmal wenn der speicher vergrößert wird, der bisher erstellte string in den neu angelegten speicher kopiert werden muss.

loop:
btst #6,$bfe001
bne.s loop
rts

Cookiie Themenstarter:in
363 Beiträge seit 2007
vor 16 Jahren

Aaaaah, das ist doch mal genau die Antwort die ich gesucht habe.
So ähnlich habe ich es mir halt gedacht, das beim Anlegen schon geschaut wird wie der String am Ende aussieht, weil ich geb ihm ja schon sämtliche Infos, der er benötigt.
Super, jetzt bin ich endgültig glücklich 🙂

Danke
Cookiie

"Hail to the King, Baby!"

0
767 Beiträge seit 2005
vor 16 Jahren

am lesbarsten - aber immer die langsamste variante - ist mit string.Format(). verwend ich recht häufig, weil die performance bei den strings nur selten verloren geht. am schnellsten verschwindet die performance bei netzwerkzugriffen (db abfragen an den server...) da zahlt sichs echt nicht aus, das select statement per StringBuilder zusammenzubauen um 0.05ms zu sparen und dann 10ms lang auf die Db zu warten.

loop:
btst #6,$bfe001
bne.s loop
rts

J
3.331 Beiträge seit 2006
vor 16 Jahren

Original von 0815Coder
... das select statement per StringBuilder zusammenzubauen ...

... ganz abgesehen davon, dass bei Sql-Befehlen sowieso unbedingt **:::

0
767 Beiträge seit 2005
vor 16 Jahren

Original von juetho

... ganz abgesehen davon, dass bei Sql-Befehlen sowieso unbedingt **:::

jetzt weiss ich wieder, wieso ich sowenig mit sql mache 🙂

loop:
btst #6,$bfe001
bne.s loop
rts