Far*_*rah 16 c# performance dynamic
在C#中将实例定义为动态意味着:
编译器不执行编译时类型检查,但运行时检查就像它对所有实例一样.
编译器不执行编译时类型检查,但运行时检查发生,与任何其他非动态实例不同.
与2相同,这会带来性能损失(微不足道的?潜在的重要性?).
Eri*_*ert 40
这个问题非常令人困惑.
在C#中将实例定义为动态意味着:
通过"定义实例",您的意思是"声明变量"吗?
编译器不执行编译时类型检查,但运行时检查就像它对所有实例一样.
"像往常一样运行时检查"是什么意思?您有什么运行时检查?您是在考虑IL验证程序执行的检查,还是在考虑由强制转换引起的运行时类型检查,或者是什么?
或许最好简单解释"动态"的作用.
首先,动态距离的透视编译一个类型.从CLR的角度来看,没有动态的东西; 在代码实际运行时,所有"动态"实例都已在生成的代码中替换为"对象".
编译器将dynamic类型的表达式完全视为object类型的表达式,除了根据实例的运行时类型在运行时分析,编译和执行该表达式的值的所有操作.目标是执行的代码具有相同的语义,就好像编译器在编译时已知运行时类型一样.
你的问题似乎与性能有关.
回答性能问题的最好方法是尝试并找出 - 如果你需要硬数字你应该怎么做就是用两种方式编写代码,使用动态和使用已知类型,然后拿出秒表并比较时间.这是了解的唯一方法.
但是,让我们从抽象层面考虑某些操作的性能影响.假设你有:
int x = 123;
int y = 456;
int z = x + y;
Run Code Online (Sandbox Code Playgroud)
如今,在大多数硬件上添加两个整数大约需要十亿分之一秒.
如果我们让它变得动态会发生什么?
dynamic x = 123;
dynamic y = 456;
dynamic z = x + y;
Run Code Online (Sandbox Code Playgroud)
现在这在运行时有什么作用?这个框123和456分为对象,它们在堆上分配内存并进行一些复制.
然后它启动DLR并询问DLR"这个代码站点已经编译过一次,x和y的类型是int和int吗?"
这种情况下的答案是否定的.然后,DLR启动C#编译器的特殊版本,该编译器分析加法表达式,执行重载解析,并吐出一个描述lambda 的表达式树,它将两个int加在一起.然后,DLR将该lambda编译为动态生成的IL,然后jit编译器将其运行.然后,DLR缓存编译状态,以便第二次发出请求时,编译器不必再执行所有操作.
这需要更长的比纳秒.它可能需要数千纳秒.
这会回答你的问题吗?我真的不明白你在这里问的是什么,但我正在做出最好的猜测.
据我所知,答案是3.
你可以这样做:
dynamic x = GetMysteriousObject();
x.DoLaundry();
Run Code Online (Sandbox Code Playgroud)
由于编译器没有进行类型检查x,它将编译此代码,假设您知道自己在做什么.
但这意味着必须进行额外的运行时检查:即检查x类型,查看它是否有一个DoLaundry不接受任何参数的方法,然后执行它.
换句话说,上面的代码有点像这样做(我不是说它是相同的,只是绘制一个比较):
object x = GetMysteriousObject();
MethodInfo doLaundry = x.GetType().GetMethod(
"DoLaundry",
BindingFlags.Instance | BindingFlags.Public
);
doLaundry.Invoke(x, null);
Run Code Online (Sandbox Code Playgroud)
这绝对不是一件轻而易举的事,但并不是说你能用肉眼看到性能问题.
我相信实现dynamic涉及到为您完成的一些非常甜蜜的幕后缓存,因此如果您再次运行此代码并且x类型相同,它将运行得更快.
不过,请不要抱我这么做.我没有那么多经验dynamic; 这只是我理解它的工作方式.
| 归档时间: |
|
| 查看次数: |
7893 次 |
| 最近记录: |