我目前正在做一些最后的测量优化,主要是为了娱乐和学习,并发现了一些让我有几个问题的东西.
一,问题:
Expression<...>我的简单加法方法(Int32 + Int32 => Int32)的版本比最小的DynamicMethod版本运行得更快?这是一个简短而完整的程序.在我的系统上,输出是:
DynamicMethod: 887 ms
Lambda: 1878 ms
Method: 1969 ms
Expression: 681 ms
Run Code Online (Sandbox Code Playgroud)
我期望lambda和方法调用具有更高的值,但DynamicMethod版本一直慢约30-50%(变化可能是由于Windows和其他程序).谁知道原因?
这是程序:
using System;
using System.Linq.Expressions;
using System.Reflection.Emit;
using System.Diagnostics;
namespace Sandbox
{
public class Program
{
public static void Main(String[] args)
{
DynamicMethod method = new DynamicMethod("TestMethod",
typeof(Int32), new Type[] { typeof(Int32), typeof(Int32) });
var il = method.GetILGenerator();
il.Emit(OpCodes.Ldarg_0);
il.Emit(OpCodes.Ldarg_1);
il.Emit(OpCodes.Add);
il.Emit(OpCodes.Ret);
Func<Int32, Int32, Int32> f1 =
(Func<Int32, Int32, Int32>)method.CreateDelegate(
typeof(Func<Int32, …Run Code Online (Sandbox Code Playgroud) 我想学习动态方法及其使用c#的实际例子.
动态方法和反射之间有什么关系吗?
请帮我.
在运行时,我正在获取类的方法名列表,我想调用这些方法.我理解如何从这里完成第一部分:http: //docs.codehaus.org/display/GROOVY/JN3535-Reflection
GroovyObject.methods.each{ println it.name }
Run Code Online (Sandbox Code Playgroud)
我似乎无法找到的信息是如何在我抓住它的名字后再调用一个方法.
我想要的是到达这里:
GroovyObject.methods.each{ GroovyObject.invokeMethod( it.name, argList) }
Run Code Online (Sandbox Code Playgroud)
我似乎找不到正确的语法.上面似乎假设我已经重载了GroovyObject类的默认invokeMethod,这不是我想要的方向.
如何为具有out-parameter 的委托定义DynamicMethod ,如下所示?
public delegate void TestDelegate(out Action a);
Run Code Online (Sandbox Code Playgroud)
假设我只想要一个将a参数设置为null调用方法的方法.
请注意,我知道处理这个问题的一个更好的方法是让方法返回Action委托,但这只是一个较大项目的简化部分,并且该方法已经返回一个值,我需要处理out参数除了它,因此问题.
我试过这个:
using System;
using System.Text;
using System.Reflection.Emit;
namespace ConsoleApplication8
{
public class Program
{
public delegate void TestDelegate(out Action a);
static void Main(String[] args)
{
var method = new DynamicMethod("TestMethod", typeof(void),
new Type[] { typeof(Action).MakeByRefType() });
var il = method.GetILGenerator();
// a = null;
il.Emit(OpCodes.Ldnull);
il.Emit(OpCodes.Starg, 0);
// return
il.Emit(OpCodes.Ret);
var del = (TestDelegate)method.CreateDelegate(typeof(TestDelegate));
Action a;
del(out a);
} …Run Code Online (Sandbox Code Playgroud) 作为一个新奇的东西,我试图看看IL与运行时生成的轻量级代码与VS编译器生成的代码有什么不同,因为我注意到VS代码往往会运行不同的性能配置文件管型.
所以我写了下面的代码::
Func<object,string> vs = x=>(string)x;
Expression<Func<object,string>> exp = x=>(string)x;
var compiled = exp.Compile();
Array.ForEach(vs.Method.GetMethodBody().GetILAsByteArray(),Console.WriteLine);
Array.ForEach(compiled.Method.GetMethodBody().GetILAsByteArray(),Console.WriteLine);
Run Code Online (Sandbox Code Playgroud)
不幸的是,这会引发异常,因为GetMethodBody显然是对表达式树生成的代码的非法操作.我怎样才能以库的方式(即不使用外部工具,除非工具有API)查看代码使用轻量级codegen生成的代码?
编辑:错误发生在第5行,编译.Method.GetMethodBody()抛出异常.
Edit2:有谁知道如何恢复方法中声明的局部变量?或者没有办法GetVariables?
我们可以使用SuperObject库通过名称调用某个对象的方法,并使用SOINvoker方法将其参数作为json字符串给出,就像在这个答案中一样
我想知道如何将创建的对象作为参数发送.我试着像发送它一样
LObjectList := TObjectList.Create;
LSuperRttiCtx := TSuperRttiContext.Create;
LSuperObjectParameter := LObjectList.ToJson(LSuperRttiCtx);
SOInvoke(MyInstantiatedObject, 'MyMethod', LSuperObjectParameter);
Run Code Online (Sandbox Code Playgroud)
但在MyMethod内部,LObjectList引用丢失了.
我究竟做错了什么?
superobject库可以在这里下载
有人可以解释或指出解释为什么运行时类型检查不会出现在下面的示例中 - 字符串属性可以设置为任何类型值...
在非常意外的地方坚持这个并且真的很惊讶
using System;
using System.Reflection;
using System.Reflection.Emit;
namespace Dynamics
{
internal class Program
{
private static void Main(string[] args)
{
var a = new A();
a.Name = "Name";
Console.WriteLine(a.Name.GetType().Name);
PropertyInfo pi = a.GetType().GetProperty("Name");
DynamicMethod method = new DynamicMethod(
"DynamicSetValue", // NAME
null, // return type
new Type[]
{
typeof(object), // 0, objSource
typeof(object), // 1, value
}, // parameter types
typeof(Program), // owner
true); // skip visibility
ILGenerator gen = method.GetILGenerator();
gen.Emit(OpCodes.Ldarg_0);
gen.Emit(OpCodes.Ldarg_1);
gen.Emit(OpCodes.Call, pi.GetSetMethod(true));
gen.Emit(OpCodes.Ret);
SetValue …Run Code Online (Sandbox Code Playgroud) 是否可以使用泛型类型参数定义DynamicMethod?MethodBuilder类具有DefineGenericParameters方法.DynamicMethod有对应的吗?例如,是否可以使用DynamicMethod创建具有签名的方法?
void T Foo<T>(T a1, int a2)
Run Code Online (Sandbox Code Playgroud) 我写了一个复制公共属性的简单对象复制器.我无法弄清楚为什么Dynamic方法比c#版本慢得多.
持续时间
C#方法:4,963毫秒
动态方法:19,924毫秒
请注意 - 当我在启动秒表之前运行动态方法时 - 持续时间不包括编译阶段.我在调试和发布模式下,在x86和x64模式下运行,从VS和命令行运行,结果大致相同(动态方法慢400%).
const int NBRECORDS = 100 * 1000 * 1000;
public class Person
{
private int mSomeNumber;
public string FirstName { get; set; }
public string LastName { get; set; }
public DateTime DateOfBirth { get; set; }
public int SomeNumber
{
get { return mSomeNumber; }
set { mSomeNumber = value; }
}
}
public static Action<T1, T2> CreateCopier<T1, T2>()
{
var meth = new DynamicMethod("copy", null, new Type[] { typeof(T1), …Run Code Online (Sandbox Code Playgroud) 所以,我最近做了一些实验,发现似乎Reflection.Emit不支持ECMA规范中的所有操作码.缺少3个操作码:
ldelem.anystelem.any no. (字首)这些操作码是否在Reflection API中不受支持,或者是否有某种方法可以生成它们?
dynamicmethod ×10
c# ×7
reflection ×4
.net ×3
il ×2
cil ×1
delphi ×1
expression ×1
groovy ×1
invoke ×1
profiling ×1
rtti ×1
superobject ×1