Schnellste (und sicherste) Methode zum Ersetzen von Zeichen in std :: string

8

Ich muss ein paar (feste) Anzahl von Zeichen in einem langen String ersetzen: Ich frage mich, was ist der schnellste, aber standardkonforme Weg.

Hier ist ein Beispielcode mit 6 verschiedenen Methoden; Im Kommentar der Methode habe ich die Zeit in Millisekunden hinzugefügt, um den Vorgang in einer Testumgebung mit optimierten Optimierungen 1 Million Mal auszuführen.

%Vor%

So scheint der schnellste Weg (5), aber ich befürchte, dass diese Methode mit der "copy-on-write" std::string -Optimierung, die viele Compiler verwenden, nicht richtig funktioniert.

IMHO (5) ist auch besser lesbar.

Ich frage mich, warum (4) doppelt so schnell ist wie (3), ich dachte, dass operator[] von std::string ziemlich optimiert ist ...

AKTUALISIEREN :

Nach dem Lesen von Kommentaren habe ich meinen Code aktualisiert, um die Google Benchmark-Bibliothek zu verwenden, und die Ergebnisse von (3) und (4) scheinen identisch zu sein. Die anderen Unterschiede gelten dennoch:

%Vor%

Also sind die Unterschiede in (3) und (4) weg, aber der Rest der Ergebnisse ist der gleiche:)

    
gabry 24.11.2015, 12:17
quelle

1 Antwort

2

Die Methode, die memcpy verwendet, ist mindestens seit C ++ 11 standardkonform, weil

  1. Wie in diese Antwort erläutert, ist die Copy-on-Write-Implementierung von std::string nicht zulässig, weil Es verstößt gegen die Standardannullierung von Iteratoren / Referenzanforderungen.

  2. Die Zeichen von

    std::string werden im zusammenhängenden Speicher gespeichert, wobei 21.4.1.5:

    zitiert wird
      

    Die char-like-Objekte in einem basic_string-Objekt sollen zusammenhängend gespeichert werden. Das heißt für jeden basic_string   Objekt s, die Identität & amp; * (s.begin () + n) = & amp; * s.begin () + n soll für alle Werte von n gelten, so dass 0   & lt; = n & lt; s.size ().

Damit ist es der schnellste Standard der Methoden in Ihrer Liste (zumindest nach Ihren Benchmark-Ergebnissen).

Tatsächlich sollte dies auch mit einer nicht standardkonformen Implementierung sicher sein schreibt copy-on-write, weil non-const operator[] eine Kopie der Zeichenfolge erstellen soll, zum Beispiel:

%Vor%

druckt

%Vor%

wenn ich es mit gcc 4.8.4 und einer ziemlich alten Version von libstdc ++ kompiliere und run. Beachten Sie, dass die Zeiger nach dem Aufruf von non-const operator[] unterschiedlich sind, was bedeutet, dass die Daten kopiert wurden.

Wenn Sie wissen, dass non-const operator[] einige Prüfungen in der COW-Implementierung durchführt, kann es möglicherweise noch schneller gehen, indem Sie const operator[] :

aufrufen %Vor%

Das ist in der Tat schneller auf meinem System:

%Vor%     
vitaut 11.12.2015, 20:45
quelle

Tags und Links