确定 C# 代码大小

5

我想检查一些类的编译代码有多大(以字节为单位)。我想优化它们的大小,但我需要知道从哪里开始。


3
你使用的语言不正确。 - ordag
1
这个想法背后是否有任何实际的理由,还是纯粹出于好奇心? - LukeH
3个回答

4

一种方法是使用反射获取MSIL的大小。您需要循环遍历所有方法、属性设置器和获取器以及构造函数,以确定MSIL的大小。此外,基于Debug与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;
}

我在寻找如何查找单个方法的MSIL大小,以猜测该方法是否可能被内联,这对我来说是一个解决方案。谢谢! - Orion Edwards

3
如果您想知道在运行时存储类/类型所需的字节数,请使用以下方法:
对于值类型,请使用sizeof(type);对于引用类型,请对每个字段/属性使用sizeof
如果想知道托管 DLL 的大小,显而易见的方法是编译 DLL 并检查文件大小。要以编程方式执行此操作,请参阅 user1027167 的回答和 CodeDomProvider 类。
另外一种可能可以在代码中实现的方法是获取每个类中生成的 IL 以及字段的 sizeof 作为(可能只是相对的)大小衡量标准。
您可以使用 MethodBase.GetMethodBody 方法来实现这一点。
一旦Roslyn(编译器作为服务)发布,(提供预览版),您可能会更轻松地并且可能更准确地获取它(因为一个类的IL不仅仅由方法和字段组成)。
如果你想知道生成 DLL 的代码大小,你需要查看类似 Reflector 的工具。

我想知道托管 DLL 中每个类的代码大小。 - Adam Kłobukowski
当你说代码大小时,是指DLL的大小还是用于生成DLL的代码的大小? - George Duckett
编译后代码的大小 = DLL :) - Adam Kłobukowski
然后,要以编程方式执行此操作,请参见我的中间答案。不过,在文件资源管理器中检查DLL的大小可能会更容易。 - George Duckett

1

假设您想知道编译后代码的字节大小,我认为您需要将其编译。如果您想自动化此过程,请看这里:

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;

变量“code”(这里是一个StringBuilder)必须包含您想要测量的类的有效源代码。编译后,您只需要查看输出程序集的大小即可。

请注意,CSharpCodeProvider.CreateCompiler 方法现已过时。您可以直接在 CSharpCodeProvider 上使用 ICodeCompiler 方法。 - George Duckett
可能是一个解决方案。我需要进行一些重构,但它可能会起作用。 - Adam Kłobukowski

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接