[英]In VB.NET, C#, etc., does the one-dot rule automatically get optimized into the code?
In VB.NET, C#, etc., something like this wouldn't get optimized, would it? 在VB.NET,C#等中,这样的东西不会得到优化,是吗?
'Bad
a.B.C.DoSomething1()
a.B.C.DoSomething2()
a.B.C.X = 5
DoSomething3(a.B.C.D)
'Good
Dim cachedReference As ClassOfC = a.B.C
cachedReference.DoSomething1()
cachedReference.DoSomething2()
cachedReference.X = 5
DoSomething3(cachedReference.D)
In ECMA-type languages at least, this is a good habit to be in to minimize how many times it goes to a
, then goes to its B
field/property, then finally goes to its C
field/property. 至少在ECMA类型的语言中,这是一个好习惯,要尽量减少它进入
a
,然后转到其B
字段/属性,最后到其C
字段/属性。 I would think that is normally the rule of thumb in any typical object-oriented or procedural language, except where there's at least a pretty solid expectation that it's just going to get optimized like that by the compiler/jit/etc. 我认为这通常是任何典型的面向对象或过程语言中的经验法则,除非至少有一个明确的期望,那就是它将像编译器/ jit / etc那样得到优化。 anyway.
无论如何。 How is this handled in typical .NET, particularly for VB.NET and C#?
在典型的.NET(特别是VB.NET和C#)中如何处理?
This, for instance, doesn't seem to mention the one-dot rule, at least pertaining to either of those two languages: https://msdn.microsoft.com/en-us/library/ms973839.aspx . 例如,这似乎没有提到单点规则,至少与这两种语言之一有关: https : //msdn.microsoft.com/zh-cn/library/ms973839.aspx 。 On the other hand, I would be very surprised if it did this in general for properties, since those are effectively methods.
另一方面,如果对属性进行一般设置,我会感到非常惊讶,因为它们是有效的方法。 It would seem to make more sense if it did this if and only if they were fields are possibly even completely trivial properties.
如果这样做,并且仅当它们是字段,甚至可能是完全无关紧要的属性时,这样做似乎更有意义。
Okay, I went ahead and tried it out for curiosity's sake. 好吧,出于好奇,我继续尝试了一下。
Given the following classes: 给定以下类别:
public class Foo
{
public Bar Bar { get; set;}
}
public class Bar
{
public Baz Baz { get; set;}
}
public class Baz
{
public string One { get; set; } = string.Empty;
public string Two { get; set; } = string.Empty;
public bool BothPopulated() => !(string.IsNullOrWhiteSpace(One) || string.IsNullOrWhiteSpace(Two));
}
public class FooFactory
{
public static Foo Create() => new Foo { Bar = new Bar { Baz = new Baz { One = "Hello", Two = "World" } } };
}
And the following method: 和以下方法:
void Main()
{
var foo = FooFactory.Create();
var cached = foo.Bar.Baz;
Console.WriteLine(cached.One);
Console.WriteLine(cached.Two);
Console.WriteLine(cached.BothPopulated());
var fooTwo = FooFactory.Create();
Console.WriteLine(fooTwo.Bar.Baz.One);
Console.WriteLine(fooTwo.Bar.Baz.Two);
Console.WriteLine(fooTwo.Bar.Baz.BothPopulated());
}
LinqPad reports the IL emitted for main in release mode as LinqPad将释放模式下的main发出的IL报告为
IL_0000: call UserQuery+FooFactory.Create
IL_0005: callvirt UserQuery+Foo.get_Bar
IL_000A: callvirt UserQuery+Bar.get_Baz
IL_000F: dup
IL_0010: callvirt UserQuery+Baz.get_One
IL_0015: call System.Console.WriteLine
IL_001A: dup
IL_001B: callvirt UserQuery+Baz.get_Two
IL_0020: call System.Console.WriteLine
IL_0025: callvirt UserQuery+Baz.BothPopulated
IL_002A: call System.Console.WriteLine // <- End of cached portion
IL_002F: call UserQuery+FooFactory.Create
IL_0034: dup
IL_0035: callvirt UserQuery+Foo.get_Bar
IL_003A: callvirt UserQuery+Bar.get_Baz
IL_003F: callvirt UserQuery+Baz.get_One
IL_0044: call System.Console.WriteLine
IL_0049: dup
IL_004A: callvirt UserQuery+Foo.get_Bar
IL_004F: callvirt UserQuery+Bar.get_Baz
IL_0054: callvirt UserQuery+Baz.get_Two
IL_0059: call System.Console.WriteLine
IL_005E: callvirt UserQuery+Foo.get_Bar
IL_0063: callvirt UserQuery+Bar.get_Baz
IL_0068: callvirt UserQuery+Baz.BothPopulated
IL_006D: call System.Console.WriteLine
IL_0072: ret
So it looks like you do save some callvirts by not drilling through the properties each time. 因此,看起来您确实通过不每次都钻取属性来保存了一些callvirt。 Whether this has any measurable impact on the JIT at run-time is not something I can answer, but it does appear to leave a smaller IL footprint.
我无法回答这是否会对运行时的JIT产生任何可衡量的影响,但是它确实留下了较小的IL占用空间。
I suspect it has basically zero impact on run-time performance. 我怀疑它对运行时性能的影响基本上为零。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.