【问题标题】:Optimization techniques in C# [closed]C# 中的优化技术 [关闭]
【发布时间】:2014-03-10 14:03:46
【问题描述】:

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

【问题讨论】:

  • 您能更具体地谈谈您的设想吗? “优化”是一个非常广泛的类别。
  • 是的,很广泛。您有具体问题吗?
  • 只是想知道除了使用字典缓存之外是否有任何方法可以优化代码。

标签: c# .net optimization


【解决方案1】:

实际上,这与您在算法中的选择有关。通常没有优化的“灵丹妙药”。

例如,使用StringBuilder 代替串联可以显着提高您的代码速度,但需要权衡取舍。如果您不连接大量字符串,则初始化 StringBuilder 所需的内存和时间比仅使用常规连接更糟糕。整个框架中有很多这样的例子,比如你在问题中提到的字典缓存。

您可以真正学习并在一天中应用于您的编码的唯一一般优化是装箱/拆箱(堆与堆栈)对性能的影响。为此,您需要了解它的含义以及如何避免或减少这样做的需要。

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

【讨论】:

  • StringBuilder 在使用迭代构建时是一个非常棒且易于实现的优化器。
【解决方案2】:

我会在下面推荐

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<int> intList = new List<int>(); 

intList.add(10)

return intList[0] + 20;

不需要使用 List 转换类型。对于整数等原始数据类型,性能提升尤其显着。

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

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

使用 & 和 | 的 If 语句必须检查语句的每个部分,然后应用“and”或“or”。另一方面,&& 和 ||一次一个地检查语句,并在满足或不满足条件时立即停止。

执行更少的代码总是可以提高性能,但它也可以避免运行时错误,请考虑以下 C# 代码:

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

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

6.智能试接

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

7.替换分区

在进行除法运算时,C# 相对较慢。一种替代方法是用乘法移位操作替换除法,以进一步优化 C#。文章详细解释了如何进行转换。

REFERENCE

【讨论】:

    【解决方案3】:

    算法也经常出现问题,通常是在循环内完成一些昂贵的事情时。通常,您要做的第一件事是分析您的应用程序,它会告诉您应用程序中最慢的部分。通常,您如何加快应用程序的速度取决于您的发现。例如,如果您的应用程序模仿文件系统,则可能是您正在递归调用数据库以向上遍历树(例如)。您可以通过将这些递归调用更改为一个扁平化的数据库调用来优化这种情况,该调用在一次调用中返回所有数据。

    同样,答案是一如既往的“视情况而定”。但是,可以在 Rico Mariani's blog 中找到更多示例和建议(回顾几年,因为他的注意力已经转移):

    【讨论】:

    • 分析您的特定应用程序可能是唯一的好建议。分析,看看什么是慢(或内存占用),并尝试减少它。
    • 我实际上是在寻找好的例子。人们使用记忆(再次缓存)进行递归。 +1 数据库示例。
    【解决方案4】:

    取决于很多事情,真的。

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

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

    【讨论】:

      【解决方案5】:

      一般来说,请确保您了解不同算法的时间复杂度,并使用这些知识明智地选择您的实现。

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

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

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

      【讨论】:

        【解决方案6】:

        我会推荐 Bill Wagner 的 Effective C#(first editionsecond edition)。他介绍了许多语言结构和技术,并解释了哪些更快以及为什么。他还谈到了许多最佳实践。

        然而,优化算法通常会比使用任何类型的语言/优化技术带来更好的结果。

        【讨论】:

        • 正如我所说的那样——这是我第一次通过的地方。
        猜你喜欢
        • 2010-09-20
        • 1970-01-01
        • 2012-12-08
        • 1970-01-01
        • 2013-09-13
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多