std::string_view é mais rápido em alguns casos.
Primeiro, std::string const&exige que os dados estejam em uma std::stringmatriz C bruta, e não em uma bruta C, char const*retornada por uma API C, std::vector<char>produzida por algum mecanismo de desserialização etc. A conversão de formato evitada evita a cópia de bytes e (se a cadeia for maior que a SBO¹ para a std::stringimplementação específica ) evita uma alocação de memória.
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] );
}
Nenhuma alocação é feita no string_viewcaso, mas haveria se fosse utilizado fooum em std::string const&vez de um string_view.
A segunda razão realmente grande é que ela permite trabalhar com substrings sem uma cópia. Suponha que você esteja analisando uma string json de 2 gigabytes (!) ². Se você analisá-lo std::string, cada nó de análise em que eles armazenam o nome ou o valor de um nó copia os dados originais da sequência de 2 gb para um nó local.
Em vez disso, se você analisá-lo como std::string_views, os nós se referem aos dados originais. Isso pode economizar milhões de alocações e reduzir pela metade os requisitos de memória durante a análise.
A aceleração que você pode obter é simplesmente ridícula.
Este é um caso extremo, mas outros casos "obtenha uma substring e trabalhe com ele" também podem gerar acelerações decentes com string_view .
Uma parte importante da decisão é o que você perde usando std::string_view . Não é muito, mas é alguma coisa.
Você perde rescisão nula implícita, e é isso. Portanto, se a mesma cadeia de caracteres for passada para 3 funções, todas as quais requerem um terminador nulo, a conversão para std::stringuma vez pode ser sensata. Portanto, se seu código precisar de um terminador nulo e você não espera que as sequências sejam alimentadas por buffers de origem C ou similares, talvez faça um std::string const&. Caso contrário, faça umastd::string_view .
Se std::string_viewhouvesse uma bandeira que declarasse que era nula encerrada (ou algo mais sofisticado), removeria até o último motivo para usar umstd::string const& .
Há um caso em que tirar um std::stringsem const&é ideal sobre um std::string_view. Se você precisar possuir uma cópia da sequência indefinidamente após a chamada, aceitar valores será eficiente. Você estará no caso do SBO (e não haverá alocações, apenas algumas cópias de caracteres para duplicá-lo) ou poderá mover o buffer alocado pelo heap para um local std::string. Com duas sobrecargas std::string&&e std::string_viewpode ser mais rápido, mas apenas marginalmente, e causaria um inchaço modesto no código (o que poderia custar todos os ganhos de velocidade).
¹ Otimização de buffer pequeno
² Caso de uso real.
std::string_viewé apenas uma abstração do par (char * begin, char * end). Você o usa ao fazer umastd::stringcópia desnecessária.