我想知道人们现在经常使用什么样的优化技术。我看到人们一直用字典和所有来缓存。速度的交易空间是唯一的出路吗?
答案 0 :(得分:4)
算法经常出现问题,通常是在循环内部进行昂贵的事情时。通常,您要做的第一件事是分析您的应用程序,它将告诉您应用程序的最慢部分。通常,您为加速应用程序所做的工作取决于您找到的内容。例如,如果您的应用程序模仿文件系统,则可能是您以递归方式调用数据库以向上移动树(例如)。您可以通过将这些递归调用更改为一个平坦的数据库调用来优化该情况,该调用将返回一次调用中的所有数据。
同样,答案是,一如既往,“它取决于”。但是,更多的例子和建议可以在Rico Mariani's blog中找到(回顾几年,因为他的重点已转移):
答案 1 :(得分:3)
真的是你在算法上的选择。通常没有优化的“银弹”。
例如,使用StringBuilder
而不是连接可以使您的代码明显更快,但需要权衡。如果你没有连接大量字符串,那么初始化StringBuilder
所需的内存和时间比使用常规连接更糟糕。整个框架中有很多这样的例子,比如你在问题中提到的字典缓存。
唯一可以学习且适用于整个日常编码的一般优化是拳击/拆箱(堆与堆栈)的性能损失。要做到这一点,你需要了解它的内容以及如何避免或减少这样做的必要性。
Microsoft的MSDN文档有2篇关于性能的文章,它们提供了许多优秀的通用技术(它们实际上只是同一篇文章的不同版本)。
答案 2 :(得分:3)
我将在下面建议
<强> 1。知道何时使用StringBuilder
您之前必须听说过,StringBuilder
对象在将字符串附加到普通字符串类型后要快得多。
The thing is StringBuilder is faster mostly with big strings. This means if you have a loop that will add to a single string for many iterations then a StringBuilder class is definitely much faster than a string type.
However if you just want to append something to a string a single time then a StringBuilder class is overkill. A simple string type variable in this case improves on resources use and readability of the C# source code.
只需在StringBuilder对象和字符串类型之间正确选择,即可优化代码。
<强> 2。比较非区分大小写的字符串
在应用程序中,有时需要比较两个字符串变量,忽略这些情况。诱人且传统的方法是将两个字符串转换为全部小写或全部大写,然后比较它们,如下所示:
str1.ToLower() == str2.ToLower()
然而,重复调用函数ToLower()是性能的瓶颈。相反,使用内置的string.Compare()函数可以提高应用程序的速度。
要检查两个字符串是否相等,忽略大小写将如下所示:
string.Compare(str1, str2, true) == 0 //Ignoring cases
当两个字符串相等时,C#string.Compare函数返回一个等于0的整数。
第3。使用string.Empty
这不是一个性能改进,因为它是一个可读性改进,但它仍然算作代码优化。尝试替换以下行:
if (str == "")
使用:
if (str == string.Empty)
这只是更好的编程实践,对性能没有负面影响。
注意,有一种流行的做法是将字符串的长度检查为0比将其与空字符串进行比较要快。虽然一旦它不再是显着的性能改进,这可能是真的。相反坚持使用string.Empty。
<强> 4。将ArrayList替换为List&lt;&gt;
在同一列表中存储多种类型的对象时,ArrayList非常有用。但是,如果要在一个ArrayList中保留相同类型的变量,则可以通过使用List&lt;&gt;来提高性能。反而是对象。
采取以下ArrayList:
ArrayList intList = new ArrayList();
intList.add(10);
return (int)intList[0] + 20;
注意它只包含整数。使用List&lt;&gt;上课好多了。要将其转换为类型化列表,只需更改变量类型:
List<int> intList = new List<int>();
intList.add(10)
return intList[0] + 20;
无需使用List&lt;&gt;转换类型。对于像整数这样的原始数据类型,性能提升尤为显着。
<强> 5。使用&amp;&amp;和||运营商强>
构建if语句时,只需确保使用double和notation(&amp;&amp;)和/或double或notation(||),(在Visual Basic中它们是AndAlso和OrElse)。
如果声明使用&amp;和|必须检查声明的每个部分,然后应用“和”或“或”。另一方面,&amp;&amp;和||一次一个地发表声明,一旦条件满足或不满足就立即停止。
执行较少的代码始终是一种性能优势,但它也可以避免运行时错误,请考虑以下C#代码:
if (object1 != null && object1.runMethod())
如果object1为null,则使用&amp;&amp; operator,object1.runMethod()将不会执行。如果&amp;&amp; operator被替换为&amp;,即使object1已知为null,object1.runMethod()也会运行,从而导致异常。
<强> 6。 Smart Try-Catch
Try-Catch语句用于捕获程序员无法控制的异常,例如连接到Web或设备。使用try语句来保持代码“简单”而不是使用if语句来避免容易出错的调用会使代码变得非常慢。重构源代码以减少try语句。
<强> 7。替换部门
在分区操作方面,C#相对较慢。一种替代方法是使用乘法移位操作替换除法以进一步优化C#。本文详细介绍了如何进行转换。
答案 3 :(得分:2)
取决于很多事情,真的。
例如,当内存成为问题并且正在创建许多临时对象时,我倾向于使用对象池。 (拥有垃圾收集器不是不负责内存分配的理由)。如果速度是重要的,那么我可能会使用不安全的指针来处理数组。
无论哪种方式,如果您发现自己在c#/ .net应用程序中使用优化技术过于挣扎,那么您可能选择了错误的语言/平台。
答案 4 :(得分:1)
通常,请确保您了解不同算法的时间复杂度,并使用该知识明智地选择您的实现。
对于.NET,本文详细介绍了优化部署到CLR的代码(尽管它也与Java或任何其他现代平台相关),并且是我读过的最好的指南之一:
http://msdn.microsoft.com/en-us/library/ms973852.aspx
将文章提炼成一句话:没有什么比它的对象的内存占用更能影响.NET应用程序的速度(使用合理的算法)。要非常小心,以尽量减少内存消耗。
答案 5 :(得分:1)
我会推荐Bill Wagner的有效C#(first edition和second edition)。他经历了许多语言结构和技术,并解释哪些更快,为什么。他也谈到了很多最佳实践。
然而,通常情况下,优化算法会比使用任何类型的语言/优化技术提供更好的结果。