在C#中定义自定义类型的属性时是否存在性能问题
本文关键字:是否 存在 性能 问题 属性 定义 自定义 类型 | 更新日期: 2023-09-27 17:57:52
假设我有四个类A、B、C和D。
D具有属性:名称(字符串)
C具有属性:D1(D型)
B具有属性:C1(C型)
A具有属性B1(类型B)
以A1作为A的实例,我可以访问:A1.B1.C1.D1.Name
这有性能问题吗?
一处房产的深度能不会对性能造成巨大影响?
或者这种层次结构有限制吗?
没有性能问题,它可以深入到你想要的程度(如果我没记错的话,会达到一定的极限。但是,如果你达到了这个极限,你会遇到其他更紧迫的问题)。
此外,虽然向下遍历对象图并不是很昂贵,但getter中的任意代码可能是。
如果链中的所有属性都是密封的(默认值),并且getter是琐碎的,那么JITter可能能够内联调用链。您将产生一系列指针查找,因此从技术上讲,这不会像a有一个Name副本那样快,但开销不太可能很大。
如果链中的任何属性都是虚拟的,那么我相信JITter将无法内联调用,并且您将产生一个或多个函数调用的开销(属性get)。尽管如此,这仍然非常小(再次假设getter是微不足道的)。
和往常一样,唯一能确定的方法就是测量。要注意你在衡量什么:如果嵌套链比A拥有自己的Name副本慢50%,那并不意味着这有什么大不了的,除非你的程序在运行时花了大量时间在Name get上——这是极不可能的!因此,首先做正确的的事情——首先使程序可读和可维护——如果测量并发现它是一个瓶颈,那么就考虑优化它。
通过一些快速评测,在我的机器上,一个一级深度的琐碎属性上的++
在3纳秒内运行,嵌套10个深度的属性在6纳秒内运行。。。因此,如果你每秒做几百万次,这可能是一件值得关注的事情,但在大多数情况下,这将是微不足道的。
如果你没有做得太多,不,这不是问题。在现实场景中,面向对象编程需要这些类型的属性,例如person.personalDetails.address.city
我已经有一段时间没有做任何.net了,所以带着应有的怀疑来接受我的答案。我认为编译器应该优化getter——除非它正在做一些非常复杂的事情。剩下的是你跳到内存中的另一个地址所支付的惩罚。例如,内存中的对象可以按任何顺序排列,如以下所示:D[其他数据]CBA.因此,对于每个get,你都要求在内存中向后提供一个地址,这可能会导致小的速度减慢和很可能的页面错误(在其他情况下也是如此)。然而,这只是为了回答你的问题。在实践中,你几乎不需要考虑到这一点。除非您正在编写一个时间关键且非常复杂的算法的内部循环,否则执行时间的差异非常接近0。
在这种情况下,如果您需要经常使用字符串,最好的做法是存储对它的引用并使用该引用,而不是调用属性链。如果你在速度上没有任何收获,至少你得到了更容易阅读、键入和维护的代码。