Recentemente stavo leggendo this article da Dave Detlefs in cui presenta alcuni casi in cui CLR esegue i limiti dell'array per controllare l'eliminazione. Ho deciso di provare questo me stesso, così ho fatto la seguente:Limiti di array Controllare l'eliminazione nel CLR?
- Inaugurato Visual Studio 2010 Ultimate SP1
- Creato un nuovo C# progetto di tipo Applicazione console (puntando .NET 4 Client Profile per impostazione predefinita)
aggiunto il seguente codice (tutte le sub-modalità sono presi direttamente da questo articolo):
class Program { static void Main(string[] args) { int[] array = new int[30]; Test_SimpleAscend(array); Test_SimpleRedundant(array, 3); foreach (int i in array) { Console.WriteLine(i); } } static void Test_SimpleAscend(int[] a) { for (int i = 0; i < a.Length; i++) a[i] = i; } static void Test_SimpleRedundant(int[] a, int i) { int k = a[i]; k = k + a[i]; } }
Switched alla modalità di rilascio; verificato che "ottimizzare il codice" è selezionata nelle opzioni di generazione
- Aggiunto un punto di interruzione a ogni accesso agli array, iniziato il debug (F5) e ha aperto la finestra SMONTAGGIO
Quindi, ecco la lo smontaggio di un [i] = io; in Test_SimpleAscend:
a[i] = i;
00000024 mov eax,dword ptr [ebp-4]
00000027 mov edx,dword ptr [ebp-8]
0000002a cmp eax,dword ptr [edx+4]
0000002d jb 00000034
0000002f call 64FD6E08
00000034 mov ecx,dword ptr [ebp-4]
00000037 mov dword ptr [edx+eax*4+8],ecx
CMP/jb/chiamata è controllo limiti, in realtà costringendo la chiamata da eseguire tiri un IndexOutOfRangeException.
Stessa cosa per tutti gli accessi di array, incluso l'accesso ridondante in Test_SimpleRedundant. Quindi c'è qualcosa di sbagliato nella mia metodologia di test, o il CLR in realtà non elimina il controllo dei limiti? Spero di sbagliarmi e, in tal caso, mi piacerebbe sapere come posso davvero ottenere i limiti dell'array controllando l'eliminazione.
Quando si dice "debug avviato", presumo che si sia avviata l'applicazione * con il debugger allegato * dall'ambiente di Visual Studio. In tal caso, è necessario assicurarsi che la compilazione JIT sia abilitata perché non è predefinita. Il compilatore JIT è quello che esegue questa ottimizzazione, non il compilatore C#. –
Cosa ti aspetti che accada se il controllo dei limiti è disabilitato? Questa è generalmente una caratteristica che le persone si aspettano di avere quando usano un linguaggio gestito come C#. –
Il modo più semplice per garantire l'ottimizzazione è in realtà abilitato per avviare l'applicazione senza eseguire il debug e quindi collegare il debugger ad esso. – svick