- r - 以节省内存的方式增长 data.frame
- ruby-on-rails - ruby/ruby on rails 内存泄漏检测
- android - 无法解析导入android.support.v7.app
- UNIX 域套接字与共享内存(映射文件)
我在 XNA 中四处寻找,发现其中的 Vector3
类使用公共(public)字段而不是属性。我尝试了一个快速基准测试,发现对于 struct
来说,差异非常显着(将两个向量加在一起 1 亿次需要 2.0 秒的属性和 1.4 秒的字段)。对于引用类型,差异似乎没有那么大,但确实存在。
那是为什么呢?我知道一个属性被编译成 get_X
和 set_X
方法,这会产生方法调用开销。但是,这些简单的 getter/setter 不是总是由 JIT 内联吗?我知道您不能保证 JIT 决定做什么,但肯定这在概率列表中相当高?还有什么可以在机器级别将公共(public)字段与属性分开?
还有一件事我一直在想:自动实现的属性 (public int Foo { get; set; }
) 为什么比公共(public)字段“更好”的面向对象设计?或者更好地说:这两个有什么不同?我知道通过反射使它成为一个属性更容易,但还有别的吗?我敢打赌这两个问题的答案是一样的。
顺便说一句:我使用的是 .NET 3.5 SP1,我认为它解决了结构方法(或 of 结构的方法,我不确定)没有内联的问题,所以这不是是吧。我想我至少在使用它,它肯定已安装,但话又说回来,我使用的是 64 位 Vista 和 SP1,它应该有 DX10.1,除了我没有 DX10.1 ..
另外:是的,我一直在运行发布版本:)
编辑:感谢大家的快速回答,但我表示我确实知道属性访问是一种方法调用,但我不知道为什么据推测,内联方法比直接字段访问慢。
编辑 2:所以我创建了另一个使用显式 GetX() 方法的 struct
(o 我如何不怀念我的 Java 时光一点) 并且无论我是否禁用内联(通过 [MethodImplAttribute(MethodImplOptions.NoInlining)]
)执行的都是一样的,所以结论:非静态方法显然从不内联,不是即使在结构上。
我认为存在异常(exception)情况,JIT 可以优化虚拟方法调用。为什么这不能发生在不知道继承的结构上,因此方法调用只能指向一个可能的方法,对吗?还是因为您可以在其上实现接口(interface)?
这有点可惜,因为它真的会让我考虑在性能关键的东西上使用属性,但使用字段让我觉得很脏,我还不如用 C 写我正在做的事情。
编辑 3:我找到了 this发布关于完全相同的主题。他的最终结论是属性调用确实得到了优化。我也可以发誓我已经读过很多次简单的 getter/setter 属性将被内联,尽管在 IL 中是 callvirt
。那我要疯了吗?
编辑 4:Reed Copsey 在下面的评论中发布了答案:
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
我对他的回答的回应:
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
谢谢大家!
最佳答案
编辑 2:
我在这里有另一个潜在的想法:
您提到您在 x64 上运行。我已经在 x86 上测试过同样的问题,并且在使用自动属性与字段时看到了相同的性能。但是,如果您查看 Connect 和邮件列表/论坛帖子,网上有很多引用资料表明 x64 CLR 的 JIT 是不同的代码库,并且具有与 x86 JIT 截然不同的性能特征。我猜这是 x64 仍然落后的地方。
此外,仅供引用,在 .net 3.5sp1 中修复的结构/方法/等问题是在 x86 方面,事实上,在 .net3 之前,将结构作为参数的方法调用永远不会在 x86 上内联。 5sp1。这与关于您的系统的讨论几乎无关。
编辑 3:
另一件事:关于 XNA 为什么要使用字段。我实际上是在他们宣布 XNA 的游戏节上。 Rico Mariani 在一次演讲中提出了许多与他博客上相同的观点。 XNA 人员在开发某些核心对象时似乎也有类似的想法。见:
http://blogs.msdn.com/ricom/archive/2006/09/07/745085.aspx
特别是,检查第 2 点。
至于为什么自动属性比公共(public)字段好:
它们允许您更改类的 v2 中的实现,并根据需要将逻辑添加到属性获取/设置例程中,而无需更改与最终用户的接口(interface)。随着时间的推移,这会对您维护库和代码的能力产生深远的影响。
---- 来自原帖 - 但发现这不是问题--------
您是否在 VS 的之外运行发布版本?这可能是为什么事情没有得到优化的一种解释。通常,如果您在 VS 中运行,即使是优化的发布版本,VS 主机进程也会禁用 JIT 的许多功能。这可能会导致性能基准发生变化。
关于c# - 为什么公共(public)领域比属性更快?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/632831/
这个问题在这里已经有了答案: 关闭 10 年前。 Possible Duplicate: When should [assembly: InternalsVisibleTo()] be used?
问题与微服务有关,当我有多个微服务提供将被订购和计费的功能/服务时。 我正在确定采用哪种方法, a) 每个可计费微服务有一个订单和一个计费服务,有各自的数据库。b) 跨所有微服务的通用订单管理和计费服
我正在尝试使用 gcloud图书馆。 (ns firengine.state (:import [com.google.cloud AuthCredentials] [com.goog
Java 允许定义以下一对类。 class Class1 { ... } public Class2 { public Class2(Class1 c1) { ... } } 如果因为 Class1
我正在尝试查找文件 1 和文件 2 中的共同行。如果公共(public)行存在,我想写入文件 2 中的行,否则打印文件 1 中的非公共(public)行。fin1 和 fin2 是这里的文件句柄。它读
好吧,这是一个满口的标题。不过,这让我明白了。这是我的代码的要点,在 jar 里: public class NetworkShared { public static class Login
我在使用 ltree 时遇到 PHP 问题来自 PostgreSQL .我在 SQL 中这样做: SELECT * FROM tabla t WHERE t.parent_path " for "OP
我知道如何为类/接口(interface)/包的子集生成 Javadoc。但是有没有办法只为公共(public)方法的一个子集生成 Javadoc? 我更喜欢能够将方法(Javadoc 标记或注释)标
这个问题在这里已经有了答案: 关闭 12 年前。 Possible Duplicates: c#: why have empty get set properties instead of usin
在我们的每个项目中,都有一个文件用于存储该项目中使用的各种SQL 语句。类的声明方式和字符串的声明方式有一些变化。 示例类声明: internal sealed class ClassName int
我根据 http://docs.jquery.com/Plugins/Authoring 定义了我的插件 (function( $ ){ var methods = { init : fu
我正在使用 Inno Setup 来构建我的安装程序,我有 C:\Users\Public文件夹硬编码在我的 [Files] 中放置一些文件的部分(Inno Setup 没有此文件夹的常量) 我的目标
我有一个 dataframe1 包含像 'ID', 'A', 'B', 'C', 'D', 'E', 'F', 'G' 这样的列. 现在,我创建了两个数据框, dataframe2 包含 'ID',
我有一个抽象类,不幸的是我无法更改它的定义,它基本上提供了一个抽象方法,有点像。 public abstract void do(Data someData, BaseInterface interf
我刚刚在重构时偶然发现了一段奇怪的代码。它看起来像是分解出两个 readString() 方法的共同部分的候选者,只是它似乎是不可能的(这对我来说是一个令人毛骨悚然的脑筋急转弯): private f
是否有解析为公用文件夹的属性?显然,我不想在目录结构中对“c:\users\public”进行硬编码,但我找不到预定义的 Property解决这个问题。是否有一种可接受的方式来指定要在此处安装和/或在
我试图将值从一个类传递到另一个类。 subPanel1 类读取全局变量,但当我通过调整监听器更新这些变量时,它不会更改值。我试图将 rc、gc 和 bc 变量从 subPanel2 类传递到 subP
我想使用具有自动属性的干净且编码较少的类。所有属性(property)都是公共(public)的。在同一类的方法中我也使用了该属性。因此,我认为这种方法是可混搭的,因为我将公共(public)属性用于
不久前,我在 Android 应用程序中创建了一个 SQLiteHelper 类。我不是 100% 确定原因,但表名和列名是嵌套公共(public)静态抽象类中的公共(public)静态最终字段。我记
这个问题已经有答案了: Cannot make a static reference to the non-static method (8 个回答) 已关闭 3 年前。 我正在为类(class)做一
我是一名优秀的程序员,十分优秀!