MSIL:比较简单算法的效率

时间:2013-12-29 14:09:16

标签: c# clr cil

我无法找到MSIL指令的比较性能列表。一种方法可能是“线越多,处理器正在做的工作越多(原则上);但是,这有多明智?

说我想比较两个简单的算法。一个私人班级成员:

private Point location;
public bool IsClose(Point locationToCheck, int distance)
{
    int deltaX = Math.Abs(this.location.X - locationToCheck.X);
    return deltaX <= distance;
}

静态功能:

public static bool IsClose(Point x, Point y, int distance)
{
    int deltaX = Math.Abs(x.X - y.Y);
    return deltaX <= distance;
}

两者都编译为正常(发布,没有标志,VS2013,.NET 4.5),IL从ILSpy复制。

MSIL(实例变量)

IL_0000: ldarg.0
IL_0001: ldflda valuetype [System.Drawing]System.Drawing.Point ClassLibrary1.Class1::location
IL_0006: call instance int32 [System.Drawing]System.Drawing.Point::get_X()
IL_000b: ldarga.s locationToCheck
IL_000d: call instance int32 [System.Drawing]System.Drawing.Point::get_X()
IL_0012: sub
IL_0013: call int32 [mscorlib]System.Math::Abs(int32)
IL_0018: stloc.0
IL_0019: ldloc.0
IL_001a: ldarg.2
IL_001b: cgt
IL_001d: ldc.i4.0
IL_001e: ceq
IL_0020: ret

MSIL(静态,本地参数)

IL_0000: ldarga.s x
IL_0002: call instance int32 [System.Drawing]System.Drawing.Point::get_X()
IL_0007: ldarga.s y
IL_0009: call instance int32 [System.Drawing]System.Drawing.Point::get_X()
IL_000e: sub
IL_000f: call int32 [mscorlib]System.Math::Abs(int32)
IL_0014: stloc.0
IL_0015: ldloc.0
IL_0016: ldarg.2
IL_0017: cgt
IL_0019: ldc.i4.0
IL_001a: ceq
IL_001c: ret

似乎使用实例变量使得algorythm首先必须加载实例(ldarg.0)然后获取属性(ldflda val...)然后执行计算(其余)只有静态需要加载本地(ldarga.s x)并执行此操作。

我的新手理解使我认为第二个会更高效,因为它不需要间接访问实例变量(this.location)而只是从{{1}中获取所有组件}。

在这种情况下,假设我实际上更喜欢静态方法,它会是最好的方法吗?在为实例方法设计这些类型的系统时是否存在偏差,因为它们方便(例如someEnemy.IsClose(thePlayer,20);听起来语言更好)。

1 个答案:

答案 0 :(得分:4)

比较IL指令的效率没有多大意义,因为IL不是实际执行的,本机机器代码(x86,x64,ARM,...)。 JIT编译器执行各种优化,因此从IL中猜测性能将非常不准确。

查看已编译的机器代码更好,但它仍然不会非常准确,特别是因为缓存(它们对性能的影响很难猜测)。

因此,当试图找出某些代码的版本更快时,您应该做的最重要的事情就是实际测量它。

当你进行测量并且你正试图理解它们时,那​​就是在查看IL或者更好的机器代码时,它会变得有用。