- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
我写了一个简单的对象复制器来复制公共(public)属性。我不明白为什么 Dynamic 方法比 c# 版本慢很多。
时长
C# 方法:4,963 毫秒
动态方法:19,924 毫秒
请注意 - 因为我在启动秒表之前运行动态方法 - 持续时间不包括编译阶段。我在调试和 Release模式、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), typeof(T2) }, restrictedSkipVisibility: true);
ILGenerator il = meth.GetILGenerator();
int cpt = 0;
var stopHere = typeof(Program).GetMethod("StopHere");
foreach (var mi1 in typeof(T1).GetProperties(BindingFlags.Public | BindingFlags.Instance))
{
var mi2 = typeof(T2).GetProperty(mi1.Name, BindingFlags.Public | BindingFlags.Instance);
if (mi1 != null && mi2 != null)
{
cpt++;
il.Emit(OpCodes.Ldarg_1);
il.Emit(OpCodes.Ldarg_0);
il.Emit(OpCodes.Callvirt, mi1.GetMethod);
il.Emit(OpCodes.Callvirt, mi2.SetMethod);
}
}
il.Emit(OpCodes.Ret);
var dlg = meth.CreateDelegate(typeof(Action<T1, T2>));
return (Action<T1, T2>)dlg;
}
static void Main(string[] args)
{
var person1 = new Person() { FirstName = "Pascal", LastName = "Ganaye", DateOfBirth = new DateTime(1909, 5, 1), SomeNumber = 23456 };
var person2 = new Person();
var copyUsingAMethod = (Action<Person, Person>)CopyPerson;
var copyUsingADynamicMethod = CreateCopier<Person, Person>();
copyUsingAMethod(person1, person2); // 4882 ms
var sw = Stopwatch.StartNew();
for (int i = 0; i < NBRECORDS; i++)
{
copyUsingAMethod(person1, person2);
}
Console.WriteLine("{0} ms", sw.ElapsedMilliseconds);
copyUsingADynamicMethod(person1, person2); // 19920 ms
sw = Stopwatch.StartNew();
for (int i = 0; i < NBRECORDS; i++)
{
copyUsingADynamicMethod(person1, person2);
}
Console.WriteLine("{0} ms", sw.ElapsedMilliseconds);
Console.ReadKey(intercept: true);
}
private static void CopyPerson(Person person1, Person person2)
{
person2.FirstName = person1.FirstName;
person2.LastName = person1.LastName;
person2.DateOfBirth = person1.DateOfBirth;
person2.SomeNumber = person1.SomeNumber;
}
据我所知,这两种方法具有相同的 IL 代码。
IL_0000: nop
IL_0001: ldarg.1
IL_0002: ldarg.0
IL_0003: callvirt System.String get_FirstName()/DuckCopy.SpeedTests.Program+Person
IL_0008: callvirt Void set_FirstName(System.String)/DuckCopy.SpeedTests.Program+Person
IL_000d: nop
IL_000e: ldarg.1
IL_000f: ldarg.0
IL_0010: callvirt System.String get_LastName()/DuckCopy.SpeedTests.Program+Person
IL_0015: callvirt Void set_LastName(System.String)/DuckCopy.SpeedTests.Program+Person
IL_001a: nop
IL_001b: ldarg.1
IL_001c: ldarg.0
IL_001d: callvirt System.DateTime get_DateOfBirth()/DuckCopy.SpeedTests.Program+Person
IL_0022: callvirt Void set_DateOfBirth(System.DateTime)/DuckCopy.SpeedTests.Program+Person
IL_0027: nop
IL_0028: ldarg.1
IL_0029: ldarg.0
IL_002a: callvirt Int32 get_SomeNumber()/DuckCopy.SpeedTests.Program+Person
IL_002f: callvirt Void set_SomeNumber(Int32)/DuckCopy.SpeedTests.Program+Person
IL_0034: nop
IL_0035: ret
如果你读了两遍,我很感激。我最初将此发布在:http://www.codeproject.com/Answers/494714/Can-27tplusfigureplusoutpluswhyplusthisplusDynamic但没有得到我希望的所有答案。
2012 年 11 月 17 日 15:11 编辑:
removed the nop
removed the extra ="" which came from I don't where.
最佳答案
这有点晚了,但是如果您在 .NET 4 中为您的所有程序集设置一些安全属性,并且您使用内置的委托(delegate)类型——或具有相同安全属性的委托(delegate)——你将会看到相当大的性能提升。
以下是您需要的属性:
[assembly: AllowPartiallyTrustedCallers]
[assembly: SecurityTransparent]
[assembly: SecurityRules(SecurityRuleSet.Level2,SkipVerificationInFullTrust=true)]
这实际上似乎有点错误。但是因为你说你的代码不会提高安全权限,你不会阻止部分信任的调用者,所以如果你使用 skipVisibility=true
完全信任,调用 Func<int,int>
委托(delegate)基本上应该避免几乎所有的权限检查。
还有一件事,因为这些是委托(delegate),如果您将它们视为实例方法,您将获得最佳性能,即使它们不是。也就是说总是使用两者之一 Delegate.CreateDelegate
接受 firstArgument
的方法参数并向您的委托(delegate)添加初始对象引用。
考虑构建 DynamicMethod
与 skipVisibility=true
,但没有指定所有者。分配所有者允许您运行 unverifiable code .你可以用它做一些非常糟糕的事情,所以我会避免它,除非你知道你在做什么。
关于c# - DynamicMethod 比已编译的 IL 函数慢得多,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13431573/
如果我运行 .NET 编译器,它会生成一个包含中间语言代码 (IL) 的文件,并将其放入一个 .exe 文件(例如)。 如果我使用像 ildasm 这样的工具,它会再次显示 IL 代码。 但是,如果我
我正在努力寻找将为对象创建引用的位置以及将在哪个阶段创建它从程序到中间代码或中间代码到 native 代码. 最佳答案 This article might help : Typically, app
我正在尝试将这个简单的类转换为 IL 代码: public class IL { Dictionary props = new Dictionary() { {"1",1} }; } 事实上,在尝
我一直在查看有关 CLR Profiling API 的一些文章,其中许多文章都谈到调用 SetILFunctionBody() 来进行实际的 IL 重写;但是,这些文章都没有真正解释您可以使用什么来
C# 编译成 IL,然后很容易使用 ILSpy 或 dotPeek 反编译回 C#。 是否有任何工具可以将相同的 IL 反编译成 F#? 即是否有一种通过 IL 将 C# 转换为 F# 的偷偷摸摸的方
像 C# 方法 IL 一样发出 IL 但获取 System.InvalidProgramException:公共(public)语言运行时检测到无效程序。 示例: public static
我想为多线程应用程序生成 IL。作为第一步 我编写了一个简单的应用程序并使用 ILSpy 检查并生成了 IL。 public class ThreadTesting { public stat
是否有任何以 VS 插件或独立应用程序形式存在的 IL 级调试器? Visual Studio 的调试器很棒,但它允许您在 HLL 代码级别或汇编语言上进行调试,您无法调试 IL。 在某些情况下,有机
我已经编辑了简化它的问题 我有一个在这样的域中工作的应用程序: http://localhost:8092/myapp 如果我访问 http://localhost:8092/myapp/ticket
我正在使用2个选择标签。它们的内容可以在网页内修改(通过javascript)。 默认情况下,grails仅采用选定的选项(如果启用了多个,则为所有选定的选项),并将其传递给 Controller
您好,我试图通过grails在Windows控制台中运行一些命令。我这个代码 def pruebaMail() { "mkdir C:\\pruebaMail".execute()
这在html中工作正常,但在gsp中却不能。 反馈: GET http://translate.google.com/translate_tts?ie=utf-8&tl=en&q=hello%20w
我一直在研究 IL,我注意到类似 Prefix1 的操作码,文档基本上告诉我不用担心。当然,这让我很好奇这些不同的前缀操作码实际上是做什么的。谷歌快速搜索没有找到任何结果,所以我想我应该问问这里的专家
我是个新手。我现在在我的域类中遇到问题。我有3个域类,患者类,护士类和 NursePatient类, NursePatient类类是一个复合键,您可以在其中查看谁是患者的主治护士,因此,如果您查看其表
当我尝试从参数分配值时,它现在无法正常工作。 System.out.println(params.test) // I see 0 int test = params.test System.ou
如果我有一个程序集,我想更新一些文件,我需要用什么工具来执行此操作? 例如,在 java 中,可以解压缩 jar 文件更新所需的 .class 并重新压缩 jar。我怎样才能在 .NET 中完成同等的
public static class Extensions { public static T Include(this System.Enum type,T value) where T:
因此我需要对 DLL 文件进行非常简单的更改。 我已经使用 Reflector 成功地将 dll 文件导出为 IL 语言,并且找到了我需要进行的更改(它只是更改了一个 URL)。因此,如果我在记事本中
更多地考虑这是一个学术问题而不是实际问题。 在重新发明轮子时,即编写一个迷你 ORM/类型映射器时,我发出了一些 IL 以将对象的属性转换为添加到 SqlCommand 的 SqlParameters
很难学习“ float ”、“溢出”、“清除”和其他一些属性,所以请帮我找到好的在线网站来学习这些属性.. 我打开了一些网站来制作类似我发现的设计 http://wix.com我很欣赏它的导航栏,所以
我是一名优秀的程序员,十分优秀!