Ich muss eine Funktion schreiben, die testet, wenn die angegebene Zeichenfolge "leer" ist, in dem Sinne, dass sie nur Leerzeichen enthält. Leerzeichen sind die folgenden:
%Vor%Die Funktion wird oft aufgerufen, also muss sie wirklich, wirklich performant sein. Aber sollte nicht zu viel Speicher (wie jedes Zeichen auf True / False in einem Array Mapping). Dinge, die ich bisher ausprobiert habe:
if (!whitespaceCharactersMap[str[index]]) ...
) - funktioniert gut genug Meine aktuelle Lösung verwendet fest codierte Vergleiche:
%Vor%Dies scheint 50-100% schneller zu funktionieren als Hash-Einstellungen (getestet in Chrome).
Sieht oder kennt jemand weitere Möglichkeiten?
Update 1
Ich werde einige der Kommentare hier beantworten:
Hier sind meine Leistungstests:
Ich wäre Ihnen dankbar, wenn Sie diese Tests ein paar Mal durchführen würden.
Vorläufige Schlussfolgerungen:
a^9*a^10*a^11...
) ist extrem schnell in Chrome und Firefox, aber nicht in Safari. Wahrscheinlich die beste Wahl für Node.js aus der Performance-Perspektive. ' '
der erste sein). Um es zusammenzufassen, für meinen Fall werde ich mich für die folgende regexp-Version entscheiden:
%Vor%Gründe:
Eine hartcodierte Lösung scheint die beste zu sein, aber ich denke, switch
sollte schneller sein. Es hängt davon ab, wie JavaScript-Interpreter diese behandelt (die meisten Compiler machen dies sehr effizient), daher ist browserspezifisch (d. H. Schnell in einigen, langsam in anderen). Außerdem bin ich mir nicht sicher, wie schnell JavaScript mit UTF-Strings ist, also könnten Sie versuchen, ein Zeichen in seinen ganzzahligen Code zu konvertieren, bevor Sie die Werte vergleichen.
Eine andere Sache, die Sie beachten sollten, ist for
zu ändern:
Bearbeiten
Ihr jsPerf-Test hat einige Änderungen erhalten, die aktuelle hier . Mein Code ist in Chrome 26 und 27 und in IE10 deutlich schneller, aber in Firefox 18 auch der langsamste.
Ich habe den gleichen Test (ich weiß nicht, wie man jsPerf diese speichern kann) auf Firefox 20.0 unter 64-bit Linux ausgeführt und es hat sich als einer der zwei schnellsten herausgestellt (gebunden mit trimTest
, beide bei etwa 11,8 M ops / s). Ich habe auch Firefox 20.0.1 auf WinXP getestet, aber unter einer VirtualBox (immer noch unter 64bit Linux, was hier einen signifikanten Unterschied machen könnte), die 10% ops / sec zu switchTest
mit% co_de gab % kommt mit 7.3M Ops / Sekunde an zweiter Stelle.
Also, ich vermute, dass die Leistung von der Browser-Version und / oder vielleicht sogar von dem zugrundeliegenden Betriebssystem / der Hardware abhängt (ich nehme an, der obige FF18-Test war auf Win). In jedem Fall müssen Sie, um eine wirklich optimale Version zu erstellen, viele Versionen erstellen, die jeweils auf allen Browsern, Betriebssystemen, Architekturen usw. getestet werden. Sie können sich darauf konzentrieren und dann auf Ihrer Seite die am besten geeignete Version hinzufügen für den Browser des Besuchers, Betriebssystem, Architektur, ... Ich bin mir nicht sicher, welche Art von Code die Mühe wert ist.
Da die Verzweigung viel teurer ist als die meisten anderen Operationen, möchten Sie die Verzweigungen auf ein Minimum reduzieren. Daher ist Ihre Sequenz von if / else-Anweisungen möglicherweise nicht sehr performant. Eine Methode, die stattdessen hauptsächlich Mathematik verwendet, wäre viel schneller. Zum Beispiel:
Eine Möglichkeit zur Durchführung einer Gleichheitsprüfung ohne Verwendung von Verzweigungen besteht in der Verwendung bitweiser Operationen. Ein Beispiel ist, zu überprüfen, dass a == b:
%Vor%Da der xor zweier ähnlicher Bits (dh 1 ^ 1 oder 0 ^ 0) 0 ist, ergibt das Xoring von zwei gleichen Werten 0. Dies ist nützlich, weil es uns erlaubt, 0 als einen "wahren" Wert zu behandeln, und mache mehr Mathe. Stellen Sie sich vor, wir haben eine Reihe boolescher Variablen, die auf diese Weise dargestellt werden: Zahlen ungleich Null sind falsch, und null bedeutet "wahr". Wenn wir fragen wollen: "Ist das wahr?" wir multiplizieren sie einfach alle zusammen. Wenn einer von ihnen wahr wäre (gleich Null), wäre das gesamte Ergebnis Null.
So würde der Code beispielsweise so aussehen:
%Vor%Der Hauptgrund, dass dies performanter wäre, als einfach etwas zu tun:
%Vor% ist, dass JavaScript Boolesche Operatoren kurzschließt, was bedeutet, dass jedes Mal, wenn der Operator ||
verwendet wird, nicht nur die Operation oder ausführt, sondern auch prüft, ob es beweisen kann, dass die Anweisung bisher wahr sein muss Dies ist eine Verzweigungsoperation, die teuer ist. Der mathematische Ansatz hingegen beinhaltet keine Verzweigung außer der if-Anweisung selbst und sollte daher viel schneller sein.
Dies erstellt und verwendet eine 'Hash' Suche nach den Zeichen der Zeichenkette, wenn es einen Nicht-Whitespace erkennt und dann false zurückgibt:
%Vor% Ich bin mir nicht sicher über die Leistung (noch) . Nach einem kurzen Test auf Jsperf, es erweist sich als ziemlich langsam im Vergleich zu RegExp mit /^\s*$/
.
bearbeiten:
Es sieht so aus, als ob die Lösung, mit der Sie arbeiten sollten, wahrscheinlich von der Art der Daten abhängt, mit denen Sie arbeiten: Sind die Daten meistens Whitespace oder meistens kein Whitespace? Auch meistens ASCII Text? Sie können es möglicherweise für durchschnittliche Testfälle beschleunigen, indem Sie Bereichsüberprüfungen (über if
) für allgemeine Zeichenbereiche ohne Leerzeichen verwenden, switch
für die häufigsten Leerzeichen verwenden und dann einen Hash-Lookup für alles andere verwenden. Dies wird wahrscheinlich die durchschnittliche Leistung der Tests verbessern, wenn die meisten der zu testenden Daten aus den gebräuchlichsten Zeichen bestehen (zwischen 0x0 und 0x7F).
Vielleicht könnte so etwas (ein Hybrid aus if / switch / hash) funktionieren:
%Vor%Tags und Links javascript performance