2011-11-21 3 views
5

Je voudrais vérifier la taille du code compilé de certaines classes (en octets). Je voudrais les optimiser pour la taille, mais j'ai besoin de savoir par où commencer.Déterminer la taille du code C#

+2

Vous utilisez la mauvaise langue. – ordag

+2

Explorateur Windows? ;-) – jadarnel27

+1

Ce désir a-t-il un raisonnement pratique ou est-il simplement une curiosité oiseuse? – LukeH

Répondre

3

Si vous voulez connaître la taille en octets nécessaire pour stocker une classe/un type lors de l'exécution.

Pour value types utilisez sizeof(type), pour reference types, utilisez sizeof sur chaque champ/propriété.


Si vous voulez connaître la taille des DLL gérées, la manière évidente est de compiler la dll et vérifier la taille du fichier. Pour ce faire, consultez la réponse de user1027167 et la classe CodeDomProvider.

Autre chose qui pourrait être faisable dans le code est d'obtenir l'IL généré de chaque méthode dans vos classes ainsi que les champs sizeof comme une mesure de (peut-être juste relative) taille. Vous pouvez utiliser la méthode MethodBase.GetMethodBody pour cela.

Une fois que le Roslyn (compiler as a service) est libéré (preview available) vous pourriez probablement obtenir plus facilement et peut-être, avec précision (comme ce ne sont pas seulement les méthodes et les champs qui constituent une classe IL.


Si vous voulez connaître la taille du code utilisé pour produire une DLL, vous devrez regarder quelque chose comme Reflector

+0

J'aimerais connaître la taille du code de chaque classe dans les DLL managées. –

+0

Quand vous dites taille de code, voulez-vous dire la taille de la DLL, ou la taille du code utilisé pour produire la DLL? –

+0

Taille du code compilé = DLL :) –

1

En supposant que vous voulez connaître la taille en octets de votre code compilé, je pense que vous devez le compiler Si vous voulez automatiser ça, regarde ça:

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 variable "code" (ici c'est un StringBuilder) doit contenir le code source valide de la classe que vous voulez mesurer. Après la compilation, il suffit de regarder quelle est la taille de l'assemblage de sortie.

+0

Notez que la méthode 'CSharpCodeProvider.CreateCompiler' est maintenant obsolète. Vous pouvez utiliser directement les méthodes 'ICodeCompiler' sur' CSharpCodeProvider'. –

+0

Peut-être une solution. J'aurais besoin de refactoring, mais ça pourrait marcher. –

3

Une méthode sera d'obtenir la taille de MSIL avec Reflection. Vous aurez besoin de parcourir toutes les méthodes, les setters de propriété et les getters, et les constructeurs pour déterminer la taille du MSIL. En outre, il y aura des différences de taille en fonction des versions de débogage et de version.

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

Je cherchais comment trouver la taille MSIL d'une seule méthode, pour deviner si une méthode serait probablement en ligne, et c'était la solution pour moi. Merci! –

Questions connexes