2011-11-21 2 views
5

Я хотел бы проверить, насколько велика скомпилированный код некоторых классов (в байтах). Я бы хотел оптимизировать их по размеру, но мне нужно знать, с чего начать.Определить размер кода C#

+2

Вы используете неправильный язык. – ordag

+2

Проводник Windows? ;-) – jadarnel27

+1

Есть ли у этого желания какие-либо практические рассуждения позади него, или это просто праздное любопытство? – LukeH

ответ

3

Если вы хотите узнать размер в байтах, необходимый для хранения класса/типа во время выполнения.

value typessizeof(type), для reference types, используйте sizeof на каждое поле/свойство.


Если вы хотите узнать размер управляемых библиотек DLL, очевидный способ для компиляции DLL и проверить размер файла. Чтобы сделать это программно, взгляните на ответ пользователя1027167 и класс CodeDomProvider.

Что-то еще, что может быть полезным в коде, это получить генерируемый IL каждого метода в ваших классах, а также поля sizeof в качестве меры (возможно, только относительного) размера.

Для этого можно использовать метод MethodBase.GetMethodBody.

После Roslyn (compiler as a service) отпускании (preview available) вы могли бы, вероятно, получить его более легко и, возможно, точно (как это не только методы и поля, которые составляют класс IL.


Если вы хотите знать размер кода, используемого для создания DLL, вам нужно будет найти что-то вроде Reflector

+0

Я хотел бы знать размер кода каждого класса в управляемой DLL. –

+0

Когда вы говорите размер кода, вы имеете в виду размер DLL или размер кода, используемого для создания DLL? –

+0

Размер скомпилированного кода = DLL :) –

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; 

Переменный «код» (здесь его StringBuilder) должен содержать действительный исходный код вашего класса, который вы хотите измерить. После компиляции вам нужно только посмотреть, какой размер имеет выходная сборка.

+0

Обратите внимание, что метод CSharpCodeProvider.CreateCompiler теперь устарел. Вы можете использовать методы 'ICodeCompiler' непосредственно на' CSharpCodeProvider'. –

+0

Может быть решением. Мне нужно будет сделать рефакторинг, но это может сработать. –

3

Один из способов - получить размер MSIL с отражением. Для определения размера MSIL вам нужно будет перебрать все методы, средства определения свойств и геттеры и конструкторы. Кроме того, будут различия в размере, основанные на сборке 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

Я искал, как найти размер MSIL одного метода, чтобы угадать, может ли метод быть встроенным, и это было для меня решением. Благодаря! –

Смежные вопросы