std::string_view
est plus rapide dans certains cas.
Tout d'abord, std::string const&
besoin de données en std::string
, et pas un C brutes tableau, une char const*
retournée par l'API C, std::vector<char>
produite par certains moteur de désérialisation, etc. L'économie de conversion de format évite la copie des octets, et (si la chaîne est plus longue que la SBO1 pour l' std::string
mise en œuvre) permet d'éviter une allocation de mémoire.
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] );
}
Pas de dotations sont fait dans l' string_view
des cas, mais il y en aurait si foo
a eu un std::string const&
au lieu de string_view
.
La deuxième vraiment grande raison est qu'il permet de travailler avec des sous-chaînes sans une copie. Supposons que vous êtes l'analyse d'un 2 go de chaîne json (!)2. Si vous analysez en std::string
, analyser nœud où ils stockent le nom ou la valeur d'un nœud copie les données d'origine à partir de la 2 go de chaîne à un nœud local.
Au lieu de cela, si vous l'analyser pour std::string_view
s, les nœuds se référer aux données originales. Cela peut sauver des millions de dotations et de réduire de moitié les besoins en mémoire lors de l'analyse.
Le speedup vous pouvez obtenir est tout simplement ridicule.
C'est un cas extrême, mais d'autres "obtenir une sous-chaîne et de travailler avec elle" cas peut aussi générer décent accélérations avec string_view
.
Une partie importante de la décision est ce que vous perdez en utilisant std::string_view
. Il n'est pas beaucoup, mais c'est quelque chose.
Vous perdez implicite de fin null, et c'est à son sujet. Donc, si la même chaîne sera passé à 3 fonctions qui nécessitent tous un terminateur null, la conversion en std::string
une fois peut être sage. Ainsi, si votre code est connu pour avoir besoin d'un terminateur null, et vous ne vous attendez pas les chaînes de la fed à partir de C-style provenant des tampons ou le genre, peut-être prendre un std::string const&
. Sinon, prendre un std::string_view
.
Si std::string_view
avaient un drapeau qui dit si c'était une valeur null (ou quelque chose de fantaisiste), il allait supprimer même le dernier de raison d'utiliser un std::string const&
.
Il y a un cas où la prise d' std::string
sans const&
est optimal plus d'un std::string_view
. Si vous avez besoin d'une copie de la chaîne indéfiniment après l'appel, en prenant en valeur efficace. Vous allez être dans le SBO cas (et pas de dotations, à seulement quelques copies de caractères pour le dupliquer), ou vous serez en mesure de déplacer le segment de mémoire-tampon alloué dans un local std::string
. Avoir deux surcharges std::string&&
et std::string_view
pourrait être plus rapide, mais seulement légèrement, et elle serait la cause de modeste augmentation du code (qui pourrait vous coûter de tous les gains de vitesse).
1 Petit Tampon De L'Optimisation
2 Réel de cas d'utilisation.