【问题标题】:Performance impact of class inheritance类继承的性能影响
【发布时间】:2018-05-12 18:33:29
【问题描述】:

所以,对于许多人来说,这似乎是一个非常奇怪的问题,但它是:

假设你有一个抽象类“Object”,它有一个抽象方法 doStuff(),有 10000 个类继承自该方法。

然后在另一个类中,您有一个“对象”字典,其中包含 100 个“对象”类型的随机对象。你对它们调用 doStuff()。

的数量对性能有影响吗?可执行文件如何找到执行哪个类的方法?这是一个跳转表,一个指针表,一个巨大的 switch-case 的等效逻辑,..?

如果它对性能有任何影响,有没有办法以不同的方式构建代码来消除这个问题?

我觉得我真的想多了。

【问题讨论】:

  • 在.Net 中,每个对象都携带了一些额外的信息,即不仅是程序员在对象是其实例的类中编写的成员。在运行时,这些额外信息用于(不仅)调用正确的DoStuff 方法。所以实际上,从 object 继承的 2 或 2000 个类在解析正确的调用方法方面没有任何区别

标签: c# performance


【解决方案1】:

调用doStuff 时不会对性能产生明显影响。

在运行时,您调用doStuff 的对象类型是已知的肯定。在编译时,您需要一个巨大的 switch 语句,因为您不知道类型。 CLR 发现您正试图在 Subclass0679 上调用 doStuff,进入该类并调用该方法。就那么简单。

这样想。 ToString()Object 中声明,所有 类继承Object。当你打电话给ToString() 时,它真的很慢吗?没有。

【讨论】:

  • 只是想再次指出我的问题是 C# 标签,而不是 java 标签。但由于相似之处,我毫不费力地相信它在那里是一样的(不过,请为其他人更正你的答案)。另外,你能详细说明一下类加载器吗?
  • @uncanny 哎呀!但在 C# 中基本相同。
【解决方案2】:

派生类的数量可能会产生一些影响。

特别是,有一万个派生类和只有 100 个对象,很有可能每次对 doStuff 的调用实际上都是对一个独特的函数的调用,与其他函数是分开的。这意味着你的缓存不会很有效。

虽然这是一个相当不现实的场景。在实际实践中不太可能出现可能是一万个不同派生类中的任何一个的集合。

从这个角度来看,.NET(整个)由大约 9900 个类组成。一个体面大小的应用程序可以轻松添加达到一万所需的数百个左右——但您所说的集合可能包括 .NET 中的 anything 以及应用程序中的任何内容。我发现很难想象这可能是有意义的情况。

【讨论】:

  • 简单示例:一个大型游戏,其中每个项目都具有完全独特的功能,因此需要运行特定的代码。在这种情况下,尽管不要切换到所有指向单个类中的函数的函数指针字典,但问题仍然存在。项目参数需要分离,所以它也有它的缺点
【解决方案3】:

如果您出于好奇而将其作为假设性问题提出,那还算公平。

但是,如果您试图过早地优化某些代码并且这是您正在做出的决策级别,我强烈建议您先集中精力让您的代码正常工作,然后使用分析器将热点识别为需要优化的区域。优化。

此外,超级优化的代码通常可读性和可维护性差很多。

除非您的代码是游戏引擎或执行一些庞大的计算,否则真的需要如此优化吗?如果代码完全与外界通信——网络、磁盘、数据库等——那么由于使用继承,这种延迟将完全使任何难以察觉的时间差异相形见绌。

【讨论】:

  • 有趣的是,它确实是专门为处理最荒谬的负载而设计的游戏引擎/框架
  • 我仍然希望算法本身比使用继承和字典更重要。使用预先计算值或设计算法等技术将值数据片段保存在处理器缓存中等。祝你好运!
猜你喜欢
  • 2011-06-21
  • 2012-07-25
  • 1970-01-01
  • 1970-01-01
  • 2019-06-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-11-20
相关资源
最近更新 更多