سؤال
باستخدام العاكس أحصل على الإخراج التالي:
.method private hidebysig static class myModelTestarea.Foo Method() cil managed
{
.maxstack 1
.locals init ([0] class myModelTestarea.Foo CS$1$0000)
L_0000: nop
L_0001: ldc.i4.0
L_0002: newarr object
L_0007: call object myModelTestarea.Program::Resolve(object[])
L_000c: castclass myModelTestarea.Foo
L_0011: stloc.0
L_0012: br.s L_0014
L_0014: ldloc.0
L_0015: ret
}
بالنسبة
private static Foo Method()
{
return (Foo)Resolve();
}
private static object Resolve( params object[] args )
{
return new Foo();
}
ماذا تفعل الخطوط 11-14؟ أدعو وظيفة واحصل على نتيجة (سطر 7). ألقي النتيجة إلى العائد الصحيح (الخط ج) - لماذا لا ترجع الآن؟
بطريقة أو بأخرى، يتم تخزين النتيجة المصبوغة كمتغير محلي - ثم هناك قفزة غير خميرة إلى السطر التالي، حيث يتم تحميل المتغير المحلي مرة أخرى. لماذا ا؟
في رأيي في خط 11-14 والمتغير المحلي يمكن حذفه ...؟
المحلول
يبدو أن بناء تصحيح الأخطاء، والذي يترك في il إضافية لمساعدة المصحح. جربه مرة أخرى في الإصدار، وينبغي أن يبدو نظافة، مع التحسين، إلخ.
.method private hidebysig static class program/Foo Method() cil managed
{
.maxstack 8
L_0000: ldc.i4.0
L_0001: newarr object
L_0006: call object program::Resolve(object[])
L_000b: castclass program/Foo
L_0010: ret
}
نصائح أخرى
هل هذا بناء تصحيح؟ من الممكن أن يكون هناك من أجل المصحح.
لقد رأيت أشياء مماثلة في أماكن أخرى - إنها دائما تقريبا غير ضارة. لا تنس أن معظم التحسين يتم ذلك بواسطة JIT، والتي يمكن أن تلاحظ أشياء مثل هذا بسهولة كافية. الجانب السلبي الوحيد هو أن المزيد من IL تلميحات إلى JIT التي لا ينبغي أن تضغط عليها الطريقة.