5

I'd like to check how big is the compiled code of some classes (in bytes). I'd like to optimize them for size, but I need to know where to start.

3 Answers3

4

One method will be to get the size of MSIL with Reflection. You will need to loop through all methods, Property setters and getters, and constructors to determine the size of the MSIL. Also, there will be differences in size based on Debug versus Release builds.

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;
}
Simon
  • 1,161
  • 7
  • 5
  • I was looking for how to find the MSIL size of a single method, to guess whether a method would likely be inlined, and this was the solution for me. Thanks! – Orion Edwards Feb 14 '13 at 01:39
3

If you want to know the size in bytes needed to store a class/type at runtime.

For value types use sizeof(type), for reference types, use sizeof on each field/property.


If you want to know the size of the managed DLLs, the obvious way is to compile the dll and check the file size. To do this programatically, take a look at user1027167's answer, and the CodeDomProvider class.

Something else that might be do-able in code is to get the generated IL of each method in your classes as well as the sizeof of fields as a measure of (maybe just relative) size.

You could use the MethodBase.GetMethodBody method for this.

Once the Roslyn (compiler as a service) is released (preview available) you could probably get it more easily and possibly, accurately (as it's not just methods and fields that make up a class' IL.


If you want to know the size of the code used to produce a DLL, you'll have to look into something like Reflector

Community
  • 1
  • 1
George Duckett
  • 29,922
  • 7
  • 92
  • 154
1

Assuming you want to know the size in bytes of your compiled code I think you have to compile it. If you want to automate it, look at this:

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;

The variable "code" (here its a StringBuilder) has to contain the valid source-code of your class you want to measure. After compilation you only have to look what size the output assembly has.

user1027167
  • 3,823
  • 6
  • 27
  • 36