C#中大型类的性能开销

15

这是一个非常学术的问题 - 我被指出我编写的WCF服务中的一个类非常长(约3000行),应该将其拆分为较小的类。

随着服务范围的不断增长,包含的方法包含许多相似的功能,因此我一直没有创建多个较小的类,现在我没问题可以这样做(除了需要花费的时间),但这让我想到了一个问题 - 相对于使用多个较小的类,单个大类是否会有显著的性能开销?如果有,为什么?


5
这实际上取决于它的使用方式、功能以及编写方式。我的猜测是应该更少地担心性能开销,而是更多地担心内存开销。 - Jeremy Holovacs
3
把一个大类代替多个小类,在性能上是否有明显的损耗?- 没有,但是......这只是设计不良。有时你无法避免,但在这种情况下,好像可以避免使用一个大类。 - Security Hound
性能方面,是指序列化吗?如果是这样,也许你违反了单一职责原则,强制发送不必要的信息。主要问题在于可维护性。 - moribvndvs
我同意这里的所有评论,这是由于一些迅速需要实现的要求而产生的,我正在将该类重构为一组更易管理和优雅的较小类,我只是好奇整体性能增益的可能性有多大。干杯! - user1330152
6个回答

19

这不会带来任何明显的差异。在考虑如此极端的微观优化之前,您应该考虑代码的可维护性,而一个大约有3000行代码的类是相当危险的。

首先编写正确且易于维护的代码。只有当您真正遇到性能问题时,才应该在做出任何关于优化的决策之前首先对应用程序进行性能分析。通常性能瓶颈将在其他地方被发现(缺乏并行处理,不良算法等)。


确实如此 - 由于有多个开发人员在这个类上工作,我很惊讶它会变得如此庞大。我们已经对服务进行了负载测试,表现非常出色,因此我很感兴趣了解是否从这个角度获得收益,但通过重构确实可以提高可管理性。谢谢! - user1330152

9
不,拥有一个大类不应影响性能。将一个大类分成更小的类甚至可能会降低性能,因为你将有更多的重定向。然而,在几乎所有情况下,影响都是微不足道的。
将一个类分成更小的部分的目的不是为了改善性能,而是为了使代码更易于阅读、修改和维护。但这已经足够的理由去这样做了。

7
性能考虑在决定添加一些设计良好的类而不是单个源文件时是最后需要担心的。更多地考虑以下问题:
- 可维护性... 在如此多的代码中进行点修复很困难。 - 可读性... 如果您不得不像疯子一样向上下滚动页面才能找到内容,那么它就不可读。 - 可重用性... 没有分解使得重用变得困难。 - 内聚性... 如果一个类中做了太多的事情,那么它可能没有任何内聚性。 - 可测试性... 祝你好运,如果要对 3000 行代码的混乱代码进行单元测试并达到合理的覆盖率。
我可以继续列举,但是大型单个源文件的思维方式似乎回溯到 VB/过程编程时代。现在,如果一个方法的圆形复杂度超过 15,或者一个类有超过几百行,我就开始感到害怕。
通常,我发现如果我重构这些 10k 行代码巨兽之一,新类的总行数最终会成为原始行数的 40% 或更少。更多的类和分解(在合理范围内)会导致更少的代码。起初看起来违反直觉,但它确实有效。

谢天谢地,我们使用了区域来逻辑上分割代码并减少页面的上下滚动情况,现在我正在将其重构为使用这些区域作为基础的单独类 - 谢谢! - user1330152
虽然我有点喜欢区域,但是有人批评微软使用区域会导致代码膨胀问题更加严重,因为这种做法只是“掩盖了问题”,并没有真正解决。 - Jeff Watkins
2
我喜欢使用区域来将我的类按构造函数、依赖项、配置、状态和方法分开。这有助于我将这些概念属性和方法分开。 - Bill Heitstuman
1
如果你需要使用区域来“隐藏”代码的某些部分以使其更易读,那么在我看来,这个类已经太大了。不要隐藏丑陋的代码,而是修复它! - Hans Løken

3
实际问题不在于性能开销,而在于可维护性和重用性。你可能听说过面向对象设计的SOLID原则,其中一些原则暗示较小的类更好。特别是,我会关注单一职责原则、开闭原则和里氏替换原则,实际上,它们都间接地暗示较小的类更好。
这些东西并不容易理解。如果你已经使用面向对象语言编程了一段时间,看到SOLID后突然感觉很有道理。但在这些灯泡点亮之前,它可能看起来有些晦涩。
就一个简单的例子而言,拥有多个类,每个类一个文件,每个类的名称合理地描述其行为,每个类都只有一个任务,从纯粹的理智角度来看,这肯定比3000行长页面更容易管理。
然后考虑一下,如果你3,000行的类中的某个部分可能在程序的另一个部分中有用……将该功能放入专用类中是封装以便重用的绝佳方式。

实际上,当我写作时,我发现我只是在揭示SOLID的方面。你最好阅读这篇文章以获取更多信息。


1
我不会说那里存在性能问题,但更多的是维护和可读性方面的问题。修改每个具有其目的的类比起使用一个庞大的单一类要容易得多,这简直荒谬。这样做违反了所有面向对象编程原则。
正如我在SO上多次警告的情况一样...人们害怕过早优化,但却不害怕写出糟糕的代码,想着"等以后出现问题再修复"。让我告诉你一些事情——超过3000行代码的类已经是一个问题了,无论它是否影响了性能。

1

这取决于类的使用方式和实例化频率。当类只被实例化一次时,例如合同服务类,性能开销通常不会很大。

当类经常被实例化时,可能会降低性能。

但在这种情况下,不要考虑性能,而是考虑设计。最好考虑支持、进一步开发和可测试性。3K LOC的类非常庞大,通常是反模式的书籍。这样的类会导致代码重复和错误,进一步的开发将是痛苦的,并且已经修复的错误会一遍又一遍地出现,代码是脆弱的。

因此,类肯定应该进行重构。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接