提高C#代码效率的方法

6

和大多数人一样,我也是改进代码效率的忠实粉丝。甚至我宁愿选择执行速度更快但代码质量可能不够优雅或干净的代码,也不愿意选择更加优雅或干净但执行速度较慢的代码。

幸运的是,在大多数情况下,更快、更高效的解决方案也是更干净、更优雅的解决方案。我以前只是一个编程爱好者,现在已经成为全职开发人员,并开始学习 C# 和 Web 开发。我已经阅读了一些关于这些主题的好书,但遗憾的是,这些书很少涵盖更细微的方面。比如说,两个完成相同任务的代码哪一个会运行得更快。这种知识大多数情况下只能通过经验获得。我请求所有的程序员在这里分享任何这样的知识。

在这里,我将从以下两篇博客文章开始。这正是我在这篇文章中寻找的内容:

附言:如果这个网站上已经有这样的东西,请告诉我。我搜索了但惊讶地没有找到。如果您知道任何涵盖此类内容的书籍,请发布。

另外,如果您从某个博客文章或一些我们都可以访问的在线资源中了解到某些内容,则最好直接发布链接。


8
你有什么问题? - Ian P
所以我们都得出结论,不应该进行过早的优化,也许原始问题应该被编辑为询问代码变慢的原因,并提供在优化那些需要修复的令人讨厌的缓慢代码部分时可以帮助的优化技巧。我对SO还不太熟悉,不确定如何做和什么是不合适的。承诺检查SO的规则和指南 :) - Antonio Bakula
是的,我基本上只是想了解根据您的经验,代码为什么会变慢的原因。 - Hari Menon
2
有四种常见的算法加速技术:缓存、编译、延迟计算和索引。——Norvig,PAIP - Ken
9个回答

16

有一些事情你应该做,例如使用泛型而不是对象来避免装箱/拆箱操作并提高代码安全性,但优化代码的最佳方式是使用性能分析器确定代码中哪些部分运行缓慢。目前有许多出色的.NET代码性能分析器可用,并且它们可以帮助确定程序的瓶颈。

通常你不需要过于关注改善代码效率的小方法,而是在编码完成后使用分析器查找瓶颈。

一个好的分析器将向你报告诸如函数执行次数、函数平均运行时间、函数峰值运行时间、函数总运行时间等统计信息。有些分析器甚至会为你绘制图表,以便你可以直观地看到程序中的主要瓶颈部分,并且你可以进一步深入子函数调用。

如果没有进行性能分析,你很可能会错误地判断程序中哪个部分运行缓慢。

一个出色且免费的.NET性能分析器例子是EQATEC Profiler


+1 如果提到了装箱/拆箱。 - kirk.burleson
3
程序员往往不擅长猜测代码的热点位置。在测量之前不要试图进行优化,往往会浪费时间。应该集中精力于良好的架构设计。 - spender
1
@spender:是的,就像一个木匠没有锤子一样,搞不好会把钉子钉歪。 - Brian R. Bondy
1
+1 提到 EQATEC - 我用过几个,其中 EQATEC 有最简单和最直观的用户界面...而且它还提供了相当有用的分析...只是它不能一直深入到代码行级别。唉。 - corlettk

8

关于这个问题,最重要的一点是:不要过早地进行优化!

只有当您当前的实现无法满足性能约束时,才有一个好的优化时机。然后,您应该使用分析器检查代码中哪些部分很慢,以及如何修复它们。

在编写第一个版本时考虑优化大多是浪费时间和精力。


3
相反,大多数实质性的优化都发生在设计阶段。 - peterchen
2
在编写第一个版本时考虑优化大多是浪费时间和精力。是也不是。如果您所说的是琐碎的东西,比如 ++ii++,那我同意。另一方面,如果您做了很多优化,您会学习避免导致性能欠佳的模式,即过度膨胀的数据结构设计、过度依赖通知、过度抽象,从而导致类似于西兰花的调用树。 - Mike Dunlavey

5

“我宁愿选择执行速度快但代码质量较差的代码,而不是更加优雅或干净但执行速度慢的代码。”

如果我正在编写游戏的像素渲染器,也许我会考虑这样做 - 但是,例如在响应用户单击按钮时,我总是会优先考虑更慢但更优雅的方法,而不是快速且粗略的方法(除非慢>几秒钟,那么我可能会重新考虑)。

我必须同意其他帖子的观点-通过分析性能剖面来确定您的慢点,然后处理这些点。从一开始就编写最优代码比它的价值更麻烦,通常你会发现你认为会很慢的地方实际上效果很好,真正的慢点会让你惊讶。


3

有一些东西非常接近我所寻找的..谢谢! - Hari Menon

2
“对于所有编程平台/语言来说,情况都是一样的。您必须使用分析器来查看代码的哪些部分运行缓慢,然后对这些部分进行优化。虽然您提供的这些链接很有价值,但不要事先进行此类操作,先进行测量,然后再进行优化。”
“编辑:”

http://www.codinghorror.com/blog/2009/01/the-sad-tragedy-of-micro-optimization-theater.html

何时使用StringBuilder?

在什么时候使用StringBuilder变得不重要或成为负担?


2

有很多技巧,但如果你认为这就是你需要的,那么你需要重新开始。任何语言的性能秘诀不在于编码技巧,而在于找到需要优化的内容

打个比方,如果你是一名警探,想要抓捕劫匪,关键不在于不同种类的监狱,而在于找到劫匪的下落

我依赖于纯手动方法进行剖析。 这个例子展示了一种找到需要优化的一系列点,导致速度提升43倍的方法。

如果你在现有应用程序上进行此操作,则可能发现缓慢性能的主要原因是过度膨胀的数据结构设计,导致了过多的通知式一致性维护,以及过多的调用树。你需要找到调用树中成本高昂且可以剪枝的调用。

完成这些后,你可能会意识到,一种使用最少的数据结构和抽象设计软件的方法将从一开始就运行更快。


0

如果您对代码进行了分析,并发现其速度不够快,则有一些微观优化技巧可以使用。这里是简短列表

要谨慎地进行微观优化——就像哈利·波特中的镜子一样:如果不小心,你会花费所有时间在那里,而没有得到很多回报。

StringBuilder和异常抛出示例是很好的例子——这些都是我曾经犯过的错误,有时会将几秒钟的时间添加到函数执行中。在分析时,我发现我个人使用了大量的周期来寻找东西。在这种情况下,我使用哈希表(或字典)缓存频繁访问的对象。


1
微观优化要明智 - 这就像《哈利·波特》中的魔镜一样。哇,我现在正式老得不适合当程序员了。 :-) - Ken

0
良好的程序架构比优化函数更能带来更好的优化效果。
最大的优化是避免在运行时代码中使用所有if else,而是将它们全部放在初始化时间。
总体而言,优化是一个不好的想法,因为最有价值的是可读性强的程序,而不是快速的程序。

0

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