2011-11-21 11 views
5

Vorrei verificare quanto è grande il codice compilato di alcune classi (in byte). Mi piacerebbe ottimizzarli per le dimensioni, ma ho bisogno di sapere da dove cominciare.Determina C# Dimensione codice

+2

Stai utilizzando la lingua sbagliata. – ordag

+2

Windows Explorer? ;-) – jadarnel27

+1

Questo desiderio ha qualche ragionamento pratico dietro, o è pura curiosità oziosa? – LukeH

risposta

3

Se si desidera conoscere la dimensione in byte necessaria per memorizzare una classe/tipo in fase di esecuzione.

Per value types utilizzare sizeof(type), per reference types, utilizzare sizeof su ogni campo/proprietà.


Se volete conoscere la dimensione delle DLL gestite, il modo più ovvio è quello di compilare il dll e verificare la dimensione del file. Per fare questo in modo programmatico, dai un'occhiata alla risposta di user1027167 e alla classe CodeDomProvider.

Qualcos'altro che potrebbe essere in grado nel codice è ottenere l'IL generato di ciascun metodo nelle classi così come lo sizeof di campi come misura della dimensione (forse solo relativa).

È possibile utilizzare il metodo MethodBase.GetMethodBody per questo.

Una volta che il Roslyn (compiler as a service) viene rilasciato (preview available) si potrebbe probabilmente ottenere più facilmente e, eventualmente, con precisione (come è non solo i metodi e campi che compongono una classe IL.


Se volete sapere il dimensione del codice utilizzato per produrre una DLL, dovrai cercare qualcosa come Reflector

+0

Mi piacerebbe conoscere la dimensione del codice di ogni classe nella DLL gestita. –

+0

Quando si dice dimensione del codice, si intende la dimensione della DLL o la dimensione del codice utilizzato per produrre la DLL? –

+0

Dimensioni del codice compilato = DLL :) –

1

Supponendo che tu voglia conoscere la dimensione in byte del tuo codice compilato penso che devi compilarlo Se vuoi automatizzare guarda, questo:

ICodeCompiler comp = (new CSharpCodeProvider().CreateCompiler()); 
CompilerParameters cp = new CompilerParameters(); 
cp.ReferencedAssemblies.Add("system.dll"); 
cp.ReferencedAssemblies.Add("system.data.dll"); 
cp.ReferencedAssemblies.Add("system.xml.dll"); 
cp.GenerateExecutable = false; 
cp.GenerateInMemory = true; 
CompilerResults cr = comp.CompileAssemblyFromSource(cp, code.ToString()); 
if (cr.Errors.HasErrors) 
{ 
    StringBuilder error = new StringBuilder(); 
    error.Append("Error Compiling Expression: "); 
    foreach (CompilerError err in cr.Errors) 
    { 
     error.AppendFormat("{0}\n", err.ErrorText); 
    } 
    throw new Exception("Error Compiling Expression: " + error.ToString()); 
} 
Assembly a = cr.CompiledAssembly; 

La variabile "codice" (qui è un StringBuilder) deve contenere il codice sorgente valido della classe che si desidera misurare. Dopo la compilazione, devi solo determinare le dimensioni del gruppo di output.

+0

Si noti che il metodo 'CSharpCodeProvider.CreateCompiler' è ora obsoleto. È possibile utilizzare direttamente i metodi 'ICodeCompiler' su' CSharpCodeProvider'. –

+0

Potrebbe essere una soluzione. Dovrei fare un po 'di refactoring, ma potrebbe funzionare. –

3

Un metodo sarà quello di ottenere la dimensione di MSIL con Reflection. Sarà necessario eseguire il ciclo di tutti i metodi, i setter e i getter della proprietà e i costruttori per determinare la dimensione di MSIL. Inoltre, ci saranno differenze di dimensioni basate sulle build di Debug versus Release.

using System.Reflection; 

int totalSize = 0; 

foreach(var mi in typeof(Example).GetMethods(BindingFlags.Public | BindingFlags.NonPublic |BindingFlags.Static | BindingFlags.Instance | BindingFlags.GetProperty | BindingFlags.SetProperty)) 
{ 
    MethodInfo mi = typeof(Example).GetMethod("MethodBodyExample"); 
    MethodBody mb = mi.GetMethodBody(); 
    totalSize += mb.GetILAsByteArray().Length; 
} 
+0

Stavo cercando come trovare la dimensione MSIL di un singolo metodo, per indovinare se un metodo sarebbe probabilmente in linea, e questa era la soluzione per me. Grazie! –

Problemi correlati