- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
给出以下代码:
using System;
using System.Reflection.Emit;
using System.Diagnostics;
using System.Reflection;
namespace ConsoleApplication1
{
class A
{
public int Do(int n)
{
return n;
}
}
public delegate int DoDelegate();
class Program
{
public static void Main(string[] args)
{
A a = new A();
Stopwatch stopwatch = Stopwatch.StartNew();
int s = 0;
for (int i = 0; i < 100000000; i++)
{
s += a.Do(i);
}
Console.WriteLine(stopwatch.ElapsedMilliseconds);
Console.WriteLine(s);
DynamicMethod dm = new DynamicMethod("Echo", typeof(int), new Type[] { typeof(int) }, true);
ILGenerator il = dm.GetILGenerator();
il.Emit(OpCodes.Ldarg_0);
il.Emit(OpCodes.Ret);
DynamicMethod dm2 = new DynamicMethod("Test", typeof(int), new Type[0]);
il = dm2.GetILGenerator();
Label loopStart = il.DefineLabel();
Label loopCond = il.DefineLabel();
il.DeclareLocal(typeof(int)); // i
il.DeclareLocal(typeof(int)); // s
// s = 0;
il.Emit(OpCodes.Ldc_I4_0);
il.Emit(OpCodes.Stloc_1);
// i = 0;
il.Emit(OpCodes.Ldc_I4_0);
il.Emit(OpCodes.Stloc_0);
il.Emit(OpCodes.Br_S, loopCond);
il.MarkLabel(loopStart);
// s += Echo(i);
il.Emit(OpCodes.Ldloc_1); // Load s
il.Emit(OpCodes.Ldloc_0); // Load i
il.Emit(OpCodes.Call, dm); // Call echo method
il.Emit(OpCodes.Add);
il.Emit(OpCodes.Stloc_1);
// i++
il.Emit(OpCodes.Ldloc_0);
il.Emit(OpCodes.Ldc_I4_1);
il.Emit(OpCodes.Add);
il.Emit(OpCodes.Stloc_0);
il.MarkLabel(loopCond);
// Check for loop condition
il.Emit(OpCodes.Ldloc_0);
il.Emit(OpCodes.Ldc_I4, 100000000);
il.Emit(OpCodes.Blt_S, loopStart);
il.Emit(OpCodes.Ldloc_1);
il.Emit(OpCodes.Ret);
DoDelegate doDel = (DoDelegate)dm2.CreateDelegate(typeof(DoDelegate));
s = doDel.Invoke(); // Dummy run to force JIT
stopwatch = Stopwatch.StartNew();
s = doDel.Invoke();
Console.WriteLine(stopwatch.ElapsedMilliseconds);
Console.WriteLine(s);
}
}
}
对 Do 方法的调用被内联。循环在大约 40 毫秒内完成。例如,如果我将 Do 设为虚函数,则它不会内联,并且循环会在 240 毫秒内完成。到目前为止,一切都很好。当我使用 ILGenerator 生成 Do 方法 (Echo),然后使用与给定 main 方法相同的循环生成 DynamicMethod 时,对 Echo 方法的调用永远不会内联,并且循环完成大约需要 240 毫秒。 MSIL 代码是正确的,因为它返回与 C# 代码相同的结果。我确信方法内联是由 JIT 完成的,所以我认为没有理由不内联 Echo 方法。
有人知道为什么这个简单的方法不会被 JIT 内联吗?
最佳答案
经过进一步调查,我得出以下结论:
我在彻底测试了许多示例并研究了最终的汇编代码后得出了这一结论。
关于.net - ILGenerator 方法内联,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8685263/
给出以下代码: using System; using System.Reflection.Emit; using System.Diagnostics; using System.Reflectio
我正在尝试构造一个泛型类型的实例并在该实例上调用一个方法。然后返回方法的结果。 var genericType = typeof(GenericType<>).MakeGenericType(type
我想得到这个: .property instance class [WorldTool.Core]WorldTool.IInputPort SomePort { .get instance c
我正在尝试使用 DynamicMethod 并尝试使用 IL 来创建一些对象。我想创建以下非常基本的对象: new Queue(new List{100}); 我已经使用 ILDASM 查看生成此代码
我正在使用 System.Reflection.Emit 为类型生成包装器。在某一时刻,原始对象可能会在访问时抛出错误 (FaultException),并且该错误应该被我的 try { } catc
Food obj = ...; ILGenerator gen = (...).GetILGenerator(); gen.Emit( ?? obj ?? ); // replace this gen
我使用 ILGenerator 生成一些 IL,这是我的代码: DynamicMethod method = new DynamicMethod("test", null, Type.EmptyTyp
按照目前的情况,这个问题不适合我们的问答形式。我们希望答案得到事实、引用或专业知识的支持,但这个问题可能会引发辩论、争论、投票或扩展讨论。如果您觉得这个问题可以改进并可能重新打开,visit the
我必须将一个对象的实例传递给一个函数,所以显然所有要作为参数的信息都将加载到评估堆栈中这是我正在寻找的代码 someClass SomeObject = new someClass(); il.Emi
使用 Ildasm 我得到了这个: .method public hidebysig virtual instance string Mymethod() cil manage
我已经编写了一些函数来使用 ILGenerator 创建一个 exe 文件。我想要的是向用户展示在不使用外部工具(如 ILDasm 或 Reflector)的情况下生成的 IL 语言。 在我的程序执行
考虑为我自己的语言制作编译器,我尝试使用 Reflection.Emit 框架生成一些 MSIL 代码。当我声明局部变量时使用 int 时它工作正常。但是,当我想声明一个尚未编译的类型的局部变量时,我
我正在使用 ILGenerator.Emit 生成动态类型。我正在生成一个方法主体,它将方法参数的类型存储在一个数组中。为了实际将元素存储在数组中,我循环遍历给定方法的参数并构建必要的 IL 来存储元
如何使用 ILGenerator 设置 .maxstack 指令? 例如,典型的 setter 方法的 .maxstack 为 2: .maxstack 2 // The evalua
我如何使用 ILGenerator.Emit(不是 LambdaExpression.Compile?因为我正在尝试寻找性能更高的解决方案)动态创建具有未知 MethodInfo 的委托(delega
我有一些代码使用 IlGenerator.Emit 使用数据读取器创建和填充通用对象。它工作得很好,但是我需要扩展它以在数据库字段名称包含下划线时填充简单的子对象。 例如,名为“Address_Lin
基本上,我试图将字节数组中的数据反序列化为对象。我正在尝试使用 UTF8 编码的 GetString 方法来读取字符串。这是我的部分代码: var mm = new DynamicMethod("ge
我正在使用 System.Reflection.Emit,有时我想从 MethodBuilder 创建一个委托(delegate): MethodBuilder fooBuilder = create
我正在尝试通过在运行时发出 IL 来编译 DynamicMethod。我希望它执行以下操作: array.OrderByDesc( /* Select Field/Property Expressio
我添加到 ILGenerator 字符串 ilGen.Emit(OpCodes.Ldarg_0); ilGen.Emit(OpCodes.Ldfld, readField); 和 ilGen.Emit
我是一名优秀的程序员,十分优秀!