std::string_view
ist in einigen Fällen schneller.
Erstens std::string const&
müssen sich die Daten in einem std::string
und nicht in einem rohen C-Array befinden, das char const*
von einer C-API zurückgegeben wird, std::vector<char>
von einer Deserialisierungs-Engine erzeugt wird usw. Die vermiedene Formatkonvertierung vermeidet das Kopieren von Bytes und (wenn die Zeichenfolge länger als die ist SBO¹ für die jeweilige std::string
Implementierung) vermeidet eine Speicherzuordnung.
void foo( std::string_view bob ) {
std::cout << bob << "\n";
}
int main(int argc, char const*const* argv) {
foo( "This is a string long enough to avoid the std::string SBO" );
if (argc > 1)
foo( argv[1] );
}
In dem string_view
Fall werden keine Zuweisungen vorgenommen , aber es würde geben, wenn foo
a std::string const&
anstelle von a genommen würde string_view
.
Der zweite wirklich große Grund ist, dass es das Arbeiten mit Teilzeichenfolgen ohne Kopie ermöglicht. Angenommen, Sie analysieren eine 2-Gigabyte-JSON-Zeichenfolge (!) ². Wenn Sie es analysieren std::string
, kopiert jeder dieser Analyseknoten, auf dem der Name oder Wert eines Knotens gespeichert ist, die Originaldaten aus der 2-GB-Zeichenfolge auf einen lokalen Knoten.
Wenn Sie es stattdessen auf std::string_view
s analysieren , beziehen sich die Knoten auf die Originaldaten. Dies kann Millionen von Zuordnungen einsparen und den Speicherbedarf während des Parsens halbieren.
Die Beschleunigung, die Sie bekommen können, ist einfach lächerlich.
Dies ist ein extremer Fall, aber auch andere Fälle, in denen Sie einen Teilstring erhalten und damit arbeiten, können zu angemessenen Beschleunigungen führen string_view
.
Ein wichtiger Teil der Entscheidung ist, was Sie durch die Verwendung verlieren std::string_view
. Es ist nicht viel, aber es ist etwas.
Sie verlieren die implizite Nullterminierung, und das war's auch schon. Wenn also dieselbe Zeichenfolge an drei Funktionen übergeben wird, für die alle ein Nullterminator erforderlich ist, kann eine Konvertierung in eine std::string
einmal sinnvoll sein. Wenn bekannt ist, dass Ihr Code einen Null-Terminator benötigt und Sie keine Zeichenfolgen erwarten, die aus Puffern im C-Stil oder ähnlichem gespeist werden, nehmen Sie möglicherweise a std::string const&
. Ansonsten nimm ein std::string_view
.
Wenn std::string_view
ein Flag angegeben wäre, ob es nullterminiert ist (oder etwas ausgefalleneres), würde es sogar den letzten Grund für die Verwendung von a entfernen std::string const&
.
Es gibt einen Fall, in dem die Einnahme von a std::string
mit no const&
über a optimal ist std::string_view
. Wenn Sie nach dem Aufruf auf unbestimmte Zeit eine Kopie der Zeichenfolge besitzen müssen, ist die Verwendung von By-Value effizient. Sie werden entweder in der SBO Fall sein (und keine Zuweisungen, nur wenige Zeichen kopiert sie zu kopieren), oder Sie werden in der Lage sein zu bewegen den Heap-zugewiesenen Puffer in eine lokale std::string
. Mit zwei Überlastungen std::string&&
undstd::string_view
könnte schneller sein, aber nur geringfügig, und es wäre bescheiden Code aufblähen verursachen (die Sie alle der Geschwindigkeit Gewinne kosten könnte).
¹ Optimierung kleiner Puffer
² Tatsächlicher Anwendungsfall.
std::string_view
ist nur eine Abstraktion des Paares (char * begin, char * end). Sie verwenden es, wennstd::string
eine unnötige Kopie erstellt wird.