C#中的优化技术

我想知道人们现在经常使用什么样的优化技术。 我看到人们一直使用字典和所有来缓存。 速度的交易空间是唯一的出路吗?

算法经常出现问题,通常是在循环内部进行昂贵的事情时。 通常,您要做的第一件事是分析您的应用程序,它将告诉您应用程序的最慢部分。 通常,您为加速应用程序所做的工作取决于您找到的内容。 例如,如果您的应用程序模仿文件系统,则可能是您以递归方式调用数据库以向上移动树(例如)。 您可以通过将这些递归调用更改为一个平坦的数据库调用来优化该情况,该调用将返回一次调用中的所有数据。

同样,答案是,一如既往,“它取决于”。 然而,在Rico Mariani的博客中可以找到更多的例子和建议(回顾几年,因为他的重点已经改变):

真的是你在算法上的选择。 通常没有优化的“银弹”。

例如,使用StringBuilder而不是串联可以使代码明显更快,但需要权衡。 如果你没有连接大量字符串,那么初始化StringBuilder所需的内存和时间比使用常规连接更糟糕。 整个框架中有很多这样的例子,比如你在问题中提到的字典缓存。

您可以在一天中真正学习并应用于编码的唯一一般优化是拳击/拆箱(堆与堆栈)的性能损失。 要做到这一点,你需要了解它是什么以及如何避免或减少这样做的必要性。

微软的MSDN文档有2篇关于性能的文章,它们提供了很多好的通用技术(它们实际上只是同一篇文章的不同版本)。

真的,取决于很多事情。

例如,当内存成为问题并且正在创建许多临时对象时,我倾向于使用对象池。 (拥有垃圾收集器不是不负责内存分配的理由)。 如果速度是重要的,那么我可能会使用不安全的指针来处理数组。

无论哪种方式,如果你发现自己在ac#/ .net应用程序中使用优化技术过于挣扎,你可能选择了错误的语言/平台。

我将在下面建议

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 <>

在同一列表中存储多种类型的对象时,ArrayList非常有用。 但是,如果要在一个ArrayList中保留相同类型的变量,则可以通过使用List <>对象来提高性能。

采取以下ArrayList:

 ArrayList intList = new ArrayList(); intList.add(10); return (int)intList[0] + 20; 

注意它只包含整数。 使用List <>类要好得多。 要将其转换为类型化列表,只需要更改变量类型:

 List intList = new List(); intList.add(10) return intList[0] + 20; 

无需使用List <>转换类型。 对于像整数这样的原始数据类型,性能提升尤为显着。

5.使用&&和|| 运营商

构建if语句时,只需确保使用double和notation(&&)和/或double或符号(||),(在Visual Basic中它们是AndAlso和OrElse)。

如果语句使用&和| 必须检查声明的每个部分,然后应用“和”或“或”。 另一方面,&&和|| 一次一个地发表声明,并在条件满足或未满足时立即停止。

执行较少的代码始终是一种性能优势,但它也可以避免运行时错误,请考虑以下C#代码:

 if (object1 != null && object1.runMethod()) 

如果object1为null,则使用&&运算符,object1.runMethod()将不会执行。 如果&&运算符替换为&,则即使已知object1为null,object1.runMethod()也会运行,从而导致exception。

6.智能尝试捕捉

Try-Catch语句用于捕获程序员无法控制的exception,例如连接到Web或设备。 使用try语句来保持代码“简单”而不是使用if语句来避免容易出错的调用会使代码变得非常慢。 重构源代码以减少try语句。

7.更换部门

在分区操作方面,C#相对较慢。 一种替代方法是使用乘法移位操作替换除法以进一步优化C#。 本文详细介绍了如何进行转换。

参考

通常,请确保您了解不同算法的时间复杂度,并使用该知识明智地选择您的实现。

特别是对于.NET,本文详细介绍了优化部署到CLR的代码(虽然它也与Java或任何其他现代平台相关),并且是我读过的最好的指南之一:

http://msdn.microsoft.com/en-us/library/ms973852.aspx

将文章提炼成一句话:没有什么比它的对象的内存占用更多​​地影响.NET应用程序的速度(使用合理的算法)。 要非常小心,以尽量减少内存消耗。

我推荐Bill Wagner的Effective C#( 第一版和第二版 )。 他经历了许多语言结构和技术,并解释哪些更快,为什么。 他也谈到了很多最佳实践。

但是,通常情况下,优化算法会比使用任何类型的语言/优化技术给出更好的结果。