2016-01-06 30 views
7

Prima di iniziare, devo dire che la mia applicazione usa molte stringhe, che sono in media abbastanza piccole e che non cambiano una volta create.Posso fare in modo che std :: string usi meno memoria?

In Visual Studio 2010, ho notato che la capacità di std :: string è di almeno 30. Anche se scrivo std::string str = "test";, la capacità di str è 30. La funzione str.shrink_to_fit() non fa nulla su questo, anche se una funzione con lo stesso il nome esiste per std :: vector e funziona come previsto, ovvero diminuendo la capacità in modo che la capacità == dimensioni.

  1. Perché lo std::string::shrink_to_fit() non funziona come previsto?
  2. Come posso garantire che la stringa allochi la quantità minima di memoria?
+0

Correlato: http://stackoverflow.com/questions/2916358/immutable-strings-vs-stdstring – JimmyB

+0

È possibile utilizzare un allocatore personalizzato per 'std :: basic_string'. Tuttavia, così facendo creerà un tipo di stringa che non è compatibile con 'std :: string'. – kfx

+0

Questo suona come la piccola ottimizzazione del buffer con un piccolo buffer piuttosto grande. Se si tratta della piccola ottimizzazione del buffer, non è possibile ridurla. –

risposta

8
  1. tuo std::string implementazione molto probabilmente utilizza una forma di del short string optimization risultante in una dimensione fissa per archi più piccoli e nessun effetto per shrink_to_fit. Si noti che shrink_to_fit non è vincolante per l'implementazione, quindi questo è effettivamente conforme.
  2. È possibile utilizzare uno vector<char> per ottenere una gestione più precisa della memoria, ma perdere alcune delle funzionalità aggiuntive di std::string. È anche possibile scrivere il proprio wrapper string che utilizza internamente uno vector.
1

Uno dei motivi che std::string::shrink_to_fit() non fa altro è che non è necessario dalla norma

Osservazioni:shrink_to_fit è una richiesta non vincolante per ridurre capacity()-size(). [Nota: la richiesta non è vincolante per consentire la latitudine per le ottimizzazioni specifiche dell'implementazione. Nota -end]

Se si vuole fare in modo la stringa si restringe quindi è possibile utilizzare il trucco swap() come

std::string(string_to_shrink).swap(string_to_shrink) 

Un altro motivo per cui questo non può funzionare è che il realizzatore di std::string è permesso di implementare short string optimization in modo da poter avere sempre una dimensione minima di 30 sull'implementazione.

+0

Il trucco di scambio è essenzialmente ciò che "shrink_to_fit" doveva sostituire. Penso che il problema qui sia l'SSO. – pmr

1

Ciò che osservate è il risultato di SSO (ottimizzazione della stringa corta), come sottolineato da altri.

Che cosa si potrebbe fare a questo proposito dipende dal tipo di utilizzo:

  • Se le stringhe sono parti di un unico grande stringa, che è tipico per l'analisi, è possibile utilizzare le classi come std::experimental::string_view, GSL string_span, Google StringPiece, LLVM's StringRef ecc. Che non memorizzano i dati stessi ma si riferiscono solo a parti di altre stringhe, fornendo un'interfaccia simile a std::string.

  • Se ci sono più copie delle stesse stringhe (specialmente lunghe), può avere senso utilizzare le stringhe CoW (copy-on-write), dove le copie condividono lo stesso buffer utilizzando il meccanismo di riferimento del contatore fino a quando non vengono modificate. (Ma essere consapevoli di aspetti negativi)

  • Se le stringhe sono molto brevi (pochi caratteri) può essere utile per scrivere una classe specializzata, qualcosa in linea con Handling short codes da Andrzej

Qualunque caso hai scelto, è importante stabilire una buona procedura di benchmarking per vedere chiaramente quale effetto (se esiste) ottieni.

Aggiornamento: dopo aver riletto l'introduzione alla domanda, penso che il terzo approccio sia il migliore per voi.

Problemi correlati