为什么公共字段比属性更快? [英] Why are public fields faster than properties?

查看:18
本文介绍了为什么公共字段比属性更快?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在 XNA 中闲逛,发现其中的 Vector3 类使用公共字段而不是属性.我尝试了一个快速基准测试,发现对于 struct 来说,差异非常显着(将两个 Vectors 相加 1 亿次需要 2.0 秒的属性和 1.4 秒的字段).对于引用类型,差异似乎并不大,但确实存在.

I was poking around in XNA and saw that the Vector3 class in it was using public fields instead of properties. I tried a quick benchmark and found that, for a struct the difference is quite dramatic (adding two Vectors together a 100 million times took 2.0s with properties and 1.4s with fields). For a reference type, the difference doesn't seem to be that large but it is there.

那是为什么?我知道一个属性被编译成 get_Xset_X 方法,这会导致方法调用开销.然而,这些简单的 getter/setter 不是总是被 JIT 内联的吗?我知道你不能保证 JIT 决定做什么,但这肯定在概率列表中相当高吗?还有什么可以在机器级别将公共字段与属性分开?

So why is that? I know that a property is compiled into get_X and set_X methods, which would incur a method call overhead. However, don't these simple getters/setters always get in-lined by the JIT? I know you can't guarantee what the JIT decides to do, but surely this is fairly high on the list of probability? What else is there that separates a public field from a property at the machine level?

我一直想知道的一件事是:自动实现的属性 (public int Foo { get; set; }) 如何比公共字段更好"的面向对象设计?或者更好地说:这两个不同有什么不同?我知道通过反射使它成为一个属性更容易,但还有别的吗?我敢打赌这两个问题的答案是一样的.

And one thing I've been wondering: how is an auto-implemented property (public int Foo { get; set; }) 'better' OO-design than a public field? Or better said: how are those two different? I know that making it a property is easier with reflection, but anything else? I bet the answer to both questions is the same thing.

顺便说一句:我正在使用 .NET 3.5 SP1,我相信它修复了带有结构的方法(或 of 结构的方法,我不确定)没有内联的问题,所以这不是不是吗.我想我至少在使用它,它肯定已安装,但话说回来,我使用的是带有 SP1 的 64 位 Vista,它应该有 DX10.1,但我没有 DX10.1 ..

BTW: I am using .NET 3.5 SP1 which I believe fixed issues where methods with structs (or methods of structs, I'm not sure) weren't in-lined, so that isn't it. I think I am using it at least, it's certainly installed but then again, I'm using Vista 64-bit with SP1 which should have DX10.1 except that I don't have DX10.1 ..

另外:是的,我一直在运行一个发布版本:)

Also: yeah, I've been running a release build :)

编辑:我很感谢大家的快速回答,但我表示我确实知道属性访问是一个方法调用,但我不知道为什么据推测,内联方法比直接字段访问慢.

EDIT: I appreciate the quick answers guys, but I indicated that I do know that a property access is a method call, but that I don't know why the, presumably, in-lined method is slower than a direct field access.

EDIT 2:所以我创建了另一个使用显式 GetX() 方法的 struct(我怎么不怀念我的 Java 日子em>) 并且无论我是否禁用内联(通过 [MethodImplAttribute(MethodImplOptions.NoInlining)]),结果都是一样的,所以结论:非静态方法显然永远不会被内联,而不是即使在结构上.

EDIT 2: So I created another struct that used explicit GetX() methods (o how I don't miss my Java days at all) and that performed the same whether I disabled in-lining on it (through [MethodImplAttribute(MethodImplOptions.NoInlining)]) or not, so conclusion: non-static methods are apparently never inlined, not even on structs.

我认为有例外,JIT 可以优化虚拟方法调用.为什么这不会发生在不知道继承的结构上,因此方法调用只能指向一个可能的方法,对吗?还是因为你可以在上面实现一个接口?

I thought that there were exceptions, where the JIT could optmize the virtual method call away. Why can't this happen on structs which know no inheritance and thus a method call can only point to one possible method, right? Or is that because you can implement an interface on it?

这有点可惜,因为它真的会让我考虑在性能关键的东西上使用属性,但是使用字段让我觉得很脏,我不妨用 C 来写我正在做的事情.

This is kind of a shame, since it will really make me think about using properties on performance critical stuff, yet using fields makes me feel dirty and I might as well write what I'm doing in C.

编辑 3:我发现 this 发布关于完全相同的主题.他的最终结论是属性调用确实得到了优化.我也可以发誓,我已经多次阅读简单的 getter/setter 属性将被内联,尽管在 IL 中是 callvirt.所以我要疯了吗?

EDIT 3: I found this posting about the exact same subject. His end conclusion is that the property call did get optimized away. I also could've sworn that I've read plenty of times that simple getter/setter properties will get in-lined, despite being callvirt in the IL. So am I going insane?

EDIT 4:Reed Copsey 在下面的评论中发布了答案:

EDIT 4: Reed Copsey posted the answer in a comment below:

回复:Edit3 - 请参阅我更新的评论:我相信这是 x86 JIT 与 x64 JIT 问题.x64 中的 JIT 没有那么成熟.随着每天都有更多 64 位系统上线,我希望 MS 能够迅速改进这一点.– 里德·科普西

Re: Edit3 - see my updated comment: I believe this is x86 JIT vs x64 JIT issues. the JIT in x64 is not as mature. I'd expect MS to improve this quickly as more 64 bit systems are coming online every day. – Reed Copsey

以及我对他的回答的回应:

And my response to his answer:

谢谢,这就是答案!我尝试强制 x86 构建,所有方法都同样快,而且比 x64 快得多.这实际上对我来说非常令人震惊,我不知道我在 64 位操作系统上生活在石器时代.– JulianR

Thanks, this is the answer! I tried forcing a x86 build and all methods are equally fast, and much faster than the x64. This is very shocking to me actually, I had no idea I was living in the stone age on my 64-bit OS.. I'll include your comment in my answer so it stands out better. – JulianR

谢谢大家!

推荐答案

Edit 2:

我在这里有另一个潜在的想法:

I had another potential thought here:

您提到您在 x64 上运行.我已经在 x86 上测试了同样的问题,并且在使用自动属性与字段时看到了相同的性能.但是,如果您查看 Connect 和邮件列表/论坛帖子,网上有很多参考资料表明 x64 CLR 的 JIT 是一个不同的代码库,并且与 x86 JIT 具有非常不同的性能特征.我猜这是 x64 仍然落后的地方.

You mentioned that you are running on x64. I've tested this same issue on x86, and seen the same performance when using auto-properties vs. fields. However, if you look around on Connect and mailing list/forum posts, there are many references online to the fact that the x64 CLR's JIT is a different code base, and has very different performance characteristics to the x86 JIT. My guess is this is one place where x64 is still lagging behind.

另外,仅供参考,.net 3.5sp1 中修复的结构/方法/等事物在 x86 端,而且将结构作为参数的方法调用永远不会在 .net3 之前在 x86 上内联.5sp1.这与关于您的系统的讨论几乎无关.

Also, FYI, the struct/method/etc thing fixed in .net 3.5sp1 was on the x86 side, and was the fact that method calls that took structs as a parameter would never be inlined on x86 prior to .net3.5sp1. That's pretty much irrelevant to this discussion on your system.

编辑 3:

另一件事:至于为什么 XNA 使用字段.我实际上是在他们宣布 XNA 的 Game Fest 上.Rico Mariani 发表了演讲,他提出了许多与他博客上相同的观点.XNA 的人在开发一些核心对象时似乎也有类似的想法.见:

Another thing: As to why XNA is using fields. I actually was at the Game Fest where they announced XNA. Rico Mariani gave a talk where he brought up many of the same points that are on his blog. It seems the XNA folks had similar ideas when they developed some of the core objects. See:

http://blogs.msdn.com/ricom/存档/2006/09/07/745085.aspx

特别是,请查看第 2 点.

Particularly, check out point #2.

至于为什么自动属性比公共字段好:

As for why automatic properties are better than public fields:

它们允许您更改类的 v2 中的实现,并根据需要将逻辑添加到属性获取/设置例程中,而无需更改最终用户的界面.随着时间的推移,这会对您维护库和代码的能力产生深远的影响.

They allow you to change the implementation in v2 of your class, and add logic into the property get/set routines as needed, without changing your interface to your end users. This can have a profound effect on your ability to maintain your library and code over time.

----来自原始帖子 - 但发现这不是问题--------

---- From original post - but discovered this wasn't the issue--------

您是否在 VS 的外部运行发布版本?这可以解释为什么事情没有得到优化.通常,如果您在 VS 中运行,即使是优化的发布版本,VS 主机进程也会禁用 JIT 的许多功能.这可能会导致性能基准发生变化.

Were you running a release build outside of VS? That can be one explanation for why things aren't being optimized. Often, if you are running in VS, even an optimized release build, the VS host process disables many functions of the JIT. This can cause performance benchmarks to change.

这篇关于为什么公共字段比属性更快?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆