cerco tale codice semplice:Perché il compilatore non può ottimizzare std :: string concat?
#include <cstdio>
#include <string>
int main()
{
const std::string s = std::string("a") + "b";
puts(s.c_str());
return 0;
}
Mi aspetto che il compilatore (gcc 4.8.2/clang 3.5.0) ottimizzare tale codice per
int main()
{
puts("ab");
return 0;
}
ma non riesco a ottenere tale risultato, provare diverse opzioni come "-Ofast", "-flto", "-static-libstdC++", ma vede sempre in uscita disassembler tre funzioni di chiamata:
...
callq 0x4017e0 <_ZNSsC2EPKcRKSaIcE>
...
callq 0x401690 <_ZNSs6appendEPKc>
...
callq 0x401490 <_ZNSs4_Rep10_M_disposeERKSaIcE>
La prima è chiamata a std :: basic_string, std :: allocator> :: basic_string (char const *, std :: allocator const &).
Quindi ci sono tutti i compilatori in giro, che possono optare per un codice simile a puts ("ab"); o almeno a "std :: string s (" ab ");"?
E se non ci sono tali compilatori, cosa rende difficile l'implementazione di tale ottimizzazione?
Aggiornamento Informazioni sull'utilizzo del mondo reale. Vedo/visto molti posti nel codice vero e proprio con tale modello:
std::string s = std::string(string_const1) + string_const2 + string_variable + string_const3;
E se le prestazioni sono importante, naturalmente, è possibile riscrivere tale codice in modo più ottimale.
Ma i compilatori moderni fanno grandi lavori per ottimizzare il codice. E gcc, ad esempio, ha funzioni __builtin per malloc/free/strcpy/strcat e così via. E se std :: basic_string da libstdC++ da gcc usa queste funzioni (malloc, free, strcpy, strcat) per una parte dell'implementazione, perché non prevedere il risultato dell'uso delle funzioni e dare una risposta.
Poiché i costruttori e gli operatori di classe C++ sono funzioni, non sono algebrici, quindi è difficile individuare le ottimizzazioni algebriche. – didierc
Non hai detto perché vuoi farlo, ma dovresti 'const std :: string s = "a" "b";' adatti alle tue esigenze? I letterali stringa si incollano automaticamente una volta scritti l'uno accanto all'altro. –
Per essere chiari, lo standard C++ consente di ottimizzare il programma a 'puts (" ab ");' o equivalente. Ma i compilatori non lo fanno. Immagino che dovresti chiedere a uno sviluppatore di compilatori, ma forse parte di esso ha a che fare con il rispetto dei desideri del programmatore. Se seguissero la regola * as-if * alla fine, ci sarebbero state molte lamentele; per esempio. fare una chiamata di sistema per scrivere qualcosa sullo schermo, o fare un sonno, non ha alcun comportamento osservabile secondo la definizione in C++ 14. –