risorse | checked iterators
perché STL è lenta in debug?
Lavorando in modalità DEBUG in ambiente Microsoft, può accadere di sperimentare un rallentamento del codice che fa uso della libreria standard. Parte della responsabilità è attribuibile ai checked iterators, un'implementazione in grado di individuare gran parte degli usi inappropriati di iteratori STL nel codice utente.
La libreria standard fornita con i compilatori VC8/VC9 contiene due implementazioni indipendenti volte al controllo del corretto uso degli iteratori; la prima, associata alla macro _SECURE_SCL, è stata sviluppata da Microsoft, mentre la seconda, associata alla macro _HAS_ITERATOR_DEBUGGING, è stata realizzata da Dinkumware, l'azienda incaricata dello sviluppo e del mantenimento della libreria STL di Microsoft.
Per attivare il controllo secure standard c++ library è necessario porre a 1 la macro _SECURE_SCL; l'uso scorretto di un iteratore STL genera un runtime error che causa la terminazione immediata del programma. Un esaustivo elenco dei controlli effettuati è riportato in[2].
L'iterator debugging feature di Dinkumware verifica la validità degli iteratori in uso. Per attivare il controllo, che è disponibile solamente in modalità DEBUG, è necessario porre a 1 la macro _HAS_ITERATOR_DEBUGGING. La dereferenziazione di un iteratore invalido genera il fallimento di un'asserzione, che causa a sua volta la visualizzazione della maschera di scelta Retry/Ignore/Abort.
L'attivazione di questa caratteristica modifica la rappresentazione in memoria dei contenitori e degli iteratori della libreria standard; per tale ragione non si possono linkare assieme moduli compilati con differenti valori di _HAS_ITERATOR_DEBUGGING. Il linker di VC10 riconosce la situazione ed emette un errore, mentre quelli di VC8 e VC9 non effettuano alcuna verifica: la responsabilità di linkare oggetti tra loro compatibili è lasciata al programmatore.
VC8/9 | Release | Debug |
---|---|---|
_SECURE_SCL | 1 | 1 |
_HAS_ITERATOR_DEBUGGING | N/A | 1 |
VC10 unifica i due controlli _SECURE_SCL e _HAS_ITERATOR_DEBUGGING sotto il cappello _ITERATOR_DEBUG_LEVEL, che può assumere uno tra i seguenti valori:
Tipicamente, _ITERATOR_DEBUG_LEVEL è impostato a 0 o 1 in RELEASE, a 2 in DEBUG.
Per ragioni di retro-compatibilià, le macro _SECURE_SCL e _HAS_ITERATOR_DEBUGGING sono ancora disponibili in VC10, con una piccola differenza nei valori di default:
VC10 | Release | Debug |
---|---|---|
_ITERATOR_DEBUG_LEVEL | 0 | 2 |
_SECURE_SCL | 0 | 1 |
_HAS_ITERATOR_DEBUGGING | N/A | 1 |
Se la lentezza si registra esclusivamente quando all'applicativo è collegato un debugger, la causa potrebbe essere l'uso del debug heap[5]:
Running under a Microsoft debugger (windbg, kd, cdb, Visual Studio Debugger) by default forces Windows to use the debug heap instead of the default heap.
L'uso del debug heap è disattivabile impostando la variabile d'ambiente _NO_DEBUG_HEAP=1.
Pagina modificata il 21/05/2012