2008-09-21 13 views
87

Auf meinem Team, wir String concatentation wie dies in der Regel tun:ist der Operator + weniger performant als StringBuffer.append()

var url = // some dynamically generated URL 
var sb = new StringBuffer(); 
sb.append("<a href='").append(url).append("'>click here</a>"); 

Offensichtlich ist die folgende ist viel besser lesbar:

var url = // some dynamically generated URL 
var sb = "<a href='" + url + "'>click here</a>"; 

Aber Die JS-Experten behaupten, dass der Operator + weniger performant ist als StringBuffer.append(). Ist das wirklich wahr?

+85

Es gibt keinen StringBuffer in Javascript – Tomas

+6

Don, haben Sie sich auf Java bezogen? –

+0

Meine Erfahrung war, dass '[.] .join ('')' einige wirklich verdrahtete Verhalten gezeigt hat, also ich zurück zu +: -/ – martyglaubitz

Antwort

45

Internet Explorer ist der einzige Browser, der wirklich von dieser Welt in der heutigen leidet. (Die Versionen 5, 6 und 7 waren Hund langsam. 8 zeigt nicht die gleiche Verschlechterung.) Außerdem wird der IE immer langsamer, je länger die Zeichenfolge ist.

Wenn Sie lange Ketten verketten müssen, verwenden Sie definitiv eine array.join-Technik. (Oder etwas StringBuffer-Wrapper um dies für Lesbarkeit.) Aber wenn Ihre Strings kurz sind, nicht stören.

36

Ja, es ist wahr, aber Sie sollten sich nicht kümmern. Geh mit dem, der leichter zu lesen ist. Wenn Sie Ihre App benchmarken müssen, konzentrieren Sie sich auf die Engpässe.

Ich würde vermuten, dass String-Verkettung wird nicht Ihr Engpass sein.

18

Versuchen Sie folgendes:

var s = ["<a href='", url, "'>click here</a>"].join(""); 
+0

Nun, der Beitrag, den Sie in Ihrer Antwort verlinkt haben, versucht den "Mythos" von Array.join, auf den meine Antwort hinweist, zu widerlegen. Also vielleicht nicht. Ich habe lediglich gepostet, was ich in der Praxis schneller gesehen habe. – Rahul

+0

liebe diese Methode der Zeichenfolge concat. – bkwdesign

8

JavaScript keinen nativen String Objekt, so dass ich davon aus, das aus einer Bibliothek, die Sie verwenden, oder ein Merkmal eines ungewöhnlichen Host-Umgebung (dh kein Browser).

Ich bezweifle, dass eine Bibliothek (geschrieben in JS) etwas schneller produzieren würde, obwohl ein natives StringBuffer-Objekt möglicherweise. Die definitive Antwort kann mit einem Profiler gefunden werden (wenn Sie in einem Browser arbeiten, wird Firebug Ihnen einen Profiler für die JS-Engine in Firefox zur Verfügung stellen).

6

In den Worten von Knuth ist "vorzeitige Optimierung die Wurzel allen Übels!" Der kleine Unterschied wird wahrscheinlich am Ende nicht viel bewirken; Ich würde den besser lesbaren wählen.

+1

Traditionell wird StringBuffer über die Verkettung verwendet, weil ersteres eine O (N) -Zeitkomplexität hat, während letzteres als O (N^2) gilt, daher ist der Unterschied für großes N signifikant (aber nicht für kleines N). In jedem Fall ist das O (N^2) -Szenario in JavaScript möglicherweise nicht der Fall, abhängig von der verwendeten Umgebung. – redcalx

0

Ja, nach den üblichen Benchmarks. E.G: http://mckoss.com/jscript/SpeedTrial.htm.

Aber für die kleinen Saiten ist dies irrelevant. Sie werden sich nur für Performances auf sehr großen Saiten interessieren. In den meisten JS-Skripten ist der Flaschenhals selten an den String-Manipulationen beteiligt, da nicht genug davon vorhanden ist.

Sie sollten besser die DOM-Manipulation beobachten.

102

Ihr Beispiel ist nicht gut, da es sehr unwahrscheinlich ist, dass die Leistung wesentlich anders ist. In Ihrem Beispiel sollte die Lesbarkeit die Leistung übertrumpfen, da der Leistungsgewinn von eins gegenüber dem anderen vernachlässigbar ist. Die Vorteile eines Arrays (StringBuffer) sind nur dann offensichtlich, wenn Sie viele Konkatentationen durchführen. Auch dann kann Ihr Kilometerstand sehr von Ihrem Browser abhängen.

Hier ist eine detaillierte Leistungsanalyse, die die Leistung unter Verwendung der verschiedenen JavaScript-Verkettungsmethoden in vielen verschiedenen Browsern zeigt; String Performance an Analysis

join() once, concat() once, join() for, += for, concat() for

Mehr:
Ajaxian >> String Performance in IE: Array.join vs += continued

+9

In Bezug auf das Diagramm, falls es nicht offensichtlich ist; weniger ist besser. – Teekin

+1

"Das Wichtigste zuerst: Mit den Leistungsverbesserungen mit IE7 müssen wir bei großen Stringoperationen nicht länger einen alternativen Pfad in Betracht ziehen. Die Verwendung von Array.join in einer iterativen Situation bringt keine größeren Vorteile als die Verwendung von + = in derselben Situation Außerdem waren die Unterschiede zu IE6 so gering, dass Sie sich nicht für diese spezielle Version interessieren müssen. " –

+2

@Chris, das stimmt nicht. Vergleichen Sie diese beiden Fideln in ** IE7 **: http://jsfiddle.net/9uS4n/5/ (schnell) vs. http://jsfiddle.net/9uS4n/2/ (langsam). Es scheint mindestens eine 1000-fache Leistungsverbesserung zu geben, wenn man die "Join()" - Technik verwendet. –

29

mit Michael Haren Einverstanden.

Bedenken Sie auch die Verwendung von Arrays und Join, wenn die Leistung tatsächlich ein Problem ist.

var buffer = ["<a href='", url, "'>click here</a>"]; 
buffer.push("More stuff"); 
alert(buffer.join("")); 
+3

Ich weiß, dass eine richtige Antwort ausgewählt wurde, aber diese Antwort hat ein nützlicheres Beispiel. –

+0

Wow, einfach wow. Vergleichen Sie diese beiden Fideln in ** IE7 **: http://jsfiddle.net/9uS4n/5/ (schnell) vs. http://jsfiddle.net/9uS4n/2/ (langsam). Mit dieser Technik scheint es eine mindestens 1000-fache Verbesserung der Leistung zu geben. –

+0

gute Technik ... – rxlky

1

Soweit ich weiß, impliziert jede Verkettung eine Speicherreallokation. So ist das Problem nicht der Operator, der es tut, die Lösung besteht darin, die Anzahl der Verkettungen zu reduzieren. Zum Beispiel tun Sie die Verkettungen außerhalb der Iterationsstrukturen, wenn Sie können.

+0

Das ist eigentlich kein schlechter Ratschlag, ich weiß nicht, warum es so stark abgelehnt wird. Ich weiß, dass es die spezifische Frage nicht beantwortet, aber es verdient Anerkennung als allgemein guter Rat. – eyelidlessness

7

Wie schon einige Anwender festgestellt haben: Dies ist für kleine Strings irrelevant.

und neue Motoren JavaScript in Firefox, Safari oder Google Chrome optimieren so

"<a href='" + url + "'>click here</a>"; 

als

so schnell ist
["<a href='", url, "'>click here</a>"].join(""); 
2

Ich mag funktionalen Stil verwenden, wie zum Beispiel:

function href(url,txt) { 
    return "<a href='" +url+ "'>" +txt+ "</a>" 
} 

function li(txt) { 
    return "<li>" +txt+ "</li>" 
} 

function ul(arr) { 
    return "<ul>" + arr.map(li).join("") + "</ul>" 
} 

document.write(
    ul(
    [ 
     href("http://url1","link1"), 
     href("http://url2","link2"), 
     href("http://url3","link3") 
    ] 
) 
) 

Dieser Stil sieht lesbar und transparent sein. Es führt zur Erstellung von Dienstprogrammen, die die Wiederholung im Code reduzieren.

Dies neigt auch dazu, Zwischenzeichenfolgen automatisch zu verwenden.

3

Es ist ziemlich einfach, einen schnellen Benchmark einzurichten und Javascript-Leistungsvariationen unter Verwendung jspref.com auszuchecken. Das war wahrscheinlich nicht da, als diese Frage gestellt wurde. Aber für Leute, die über diese Frage stolpern, sollten sie sich die Seite ansehen.

Ich habe einen schnellen Test der verschiedenen Methoden der Verkettung bei http://jsperf.com/string-concat-methods-test.

+0

Demnach sieht es heutzutage so aus, dass die Verkettung mit dem + Operator definitiv der richtige Weg ist. Es sei denn, ich lese es falsch. Das ist völlig plausibel. – Richard

4

Die leichter zu lesende Methode spart Menschen wahrnehmbare Zeit bei der Betrachtung des Codes, während die "schnellere" Methode nur unmerkliche und wahrscheinlich vernachlässigbare Mengen an Zeit verschwendet, wenn Leute die Seite durchsuchen.

Ich weiß, dass dieser Beitrag lahm ist, aber ich habe versehentlich etwas völlig anderes geschrieben, dass dies ein anderer Thread war und ich nicht weiß, wie man Beiträge löscht. Mein schlechter ...

Verwandte Themen