C#中的优化技术

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/486021/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-04 05:17:37  来源:igfitidea点击:

Optimization techniques in C#

c#.netoptimization

提问by Tom

I am wondering what kind of optimization techniques people often use nowadays. I have seen people do caching all the time with dictionary and all. Is the trading space for speed the only way to go?

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

回答by Trap

Depends on a lot of things, really.

取决于很多事情,真的。

As an example, when memory becomes an issue and a lot of temporary objects are being created I tend to use object pools. (Having a garbage-collector is not a reason to not take care of memory allocation). If speed is what matters then I might use unsafe pointers to work with arrays.

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

Either way, if you find yourself struggling too much with optimization techniques in a c#/.net application you probably chose the wrong language/platform.

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

回答by benjismith

In general, make sure you understand the time complexity of different algorithms, and use that knowledge to choose your implementations wisely.

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

For .NET in particular, this article goes into great detail about optimizing code deployed to the CLR (though it's also relevant for Java, or any other modern platform), and is one of the best guides I've ever read:

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

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

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

To distill the article into one sentence: Nothing affects the speed of a .NET application (with sensible algorithms) more than the memory-footprint of its objects. Be very careful to minimize your memory consumption.

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

回答by tsimon

There are often problems with algorithms as well, usually when something expensive is done inside of a loop. Generally, the first thing you do is profile your application, which will tell you the slowest part(s) of the application. Generally, what you do to speed up your application depends upon what you find. For example, if your application mimics a file system, it may be that you're calling the database recursively to travel up the tree (for instance). You may optimise that case by changing those recursive calls into one flattened database call that returns all of the data in one call.

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

Again, the answer is, as always, 'it depends'. However, more examples and advice can be found in Rico Mariani's blog(browse back a few years, as his focus has shifted):

同样,答案一如既往地“视情况而定”。然而,更多的例子和建议可以在Rico Mariani 的博客中找到(回顾几年,因为他的重点已经转移):

回答by Dan Herbert

Really it's about your choice in algorithms. Usually there is no "silver bullet" for optimization.

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

For example, using a StringBuilderinstead of concatenation can make your code significantly faster, but there is a tradeoff. If you aren't concatenating huge sets of strings, the memory and time it takes to initialize StringBuilderis worse than just using regular concatenation. There are a lot of examples of this throughout the framework, such as dictionary caching as you mentioned in your question.

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

The only general optimization you can really learnand apply to your coding throughout your day is the performance hit from boxing/unboxing (heap vs. stack). To do this you need to learn what it's about and how to avoid, or reduce the need to do it.

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

Microsoft's MSDN documentation has 2 articles on performance that give a lot of good general purpose techniques to use (they're really just different versions of the same article).

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

回答by pbz

I would recommend Effective C# by Bill Wagner (first editionand second edition). He goes through a number of language constructs and techniques and explains which ones are faster and why. He touches on a lot of best practices as well.

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

More often than not, however, optimizing your algorithm will give you far better results than using any kind of language / optimization technique.

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

回答by Amit

I will suggest below

我会在下面建议

1. Knowing when to use StringBuilder

1. 知道何时使用 StringBuilder

You must have heard before that a StringBuilderobject is much faster at appending strings together than normal string types.

您之前一定听说过,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.

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.

Simply choosing correctly between StringBuilder objects and string types you can optimize your code.

只需在 StringBuilder 对象和字符串类型之间正确选择,您就可以优化您的代码。

2. Comparing Non-Case-Sensitive Strings

2. 比较不区分大小写的字符串

In an application sometimes it is necessary to compare two string variables, ignoring the cases. The tempting and traditionally approach is to convert both strings to all lower case or all upper case and then compare them, like such:

在应用程序中,有时需要比较两个字符串变量,忽略大小写。诱人的传统方法是将两个字符串都转换为全部小写或全部大写,然后比较它们,如下所示:

str1.ToLower() == str2.ToLower()

str1.ToLower() == str2.ToLower()

However repetitively calling the function ToLower() is a bottleneck in performace. By instead using the built-in string.Compare() function you can increase the speed of your applications.

然而,重复调用函数 ToLower() 是性能的瓶颈。通过使用内置的 string.Compare() 函数,您可以提高应用程序的速度。

To check if two strings are equal ignoring case would look like this:

要检查两个字符串是否相等,忽略大小写如下所示:

string.Compare(str1, str2, true) == 0 //Ignoring cases

string.Compare(str1, str2, true) == 0 //Ignoring cases

The C# string.Compare function returns an integer that is equal to 0 when the two strings are equal.

当两个字符串相等时,C# string.Compare 函数返回一个等于 0 的整数。

3. Use string.Empty

3. 使用 string.Empty

This is not so much a performance improvement as it is a readability improvement, but it still counts as code optimization. Try to replace lines like:

这与其说是性能改进,不如说是可读性改进,但它仍然算作代码优化。尝试替换如下行:

if (str == "")

if (str == "")

with:

和:

if (str == string.Empty)

if (str == string.Empty)

This is simply better programming practice and has no negative impact on performance.

这只是更好的编程实践,对性能没有负面影响。

Note, there is a popular practice that checking a string's length to be 0 is faster than comparing it to an empty string. While that might have been true once it is no longer a significant performance improvement. Instead stick with string.Empty.

请注意,有一种流行的做法是将字符串的长度检查为 0 比将其与空字符串进行比较要快。虽然一旦它不再是显着的性能改进,这可能是正确的。而是坚持使用 string.Empty。

4. Replace ArrayList with List<>

4. 用 List<> 替换 ArrayList

ArrayList are useful when storing multiple types of objects within the same list. However if you are keeping the same type of variables in one ArrayList, you can gain a performance boost by using List<> objects instead.

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

Take the following ArrayList:

采用以下 ArrayList:

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

Notice it only contains intergers. Using the List<> class is a lot better. To convert it to a typed List, only the variable types need to be changed:

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

List<int> intList = new List<int>(); 

intList.add(10)

return intList[0] + 20;

There is no need to cast types with List<>. The performance increase can be especially significant with primitive data types like integers.

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

5. Use && and || operators

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

When building if statements, simply make sure to use the double-and notation (&&) and/or the double-or notation (||), (in Visual Basic they are AndAlso and OrElse).

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

If statements that use & and | must check every part of the statement and then apply the "and" or "or". On the other hand, && and || go thourgh the statements one at a time and stop as soon as the condition has either been met or not met.

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

Executing less code is always a performace benefit but it also can avoid run-time errors, consider the following C# code:

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

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

If object1 is null, with the && operator, object1.runMethod()will not execute. If the && operator is replaced with &, object1.runMethod() will run even if object1 is already known to be null, causing an exception.

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

6. Smart Try-Catch

6. 智能试捕

Try-Catch statements are meant to catch exceptions that are beyond the programmers control, such as connecting to the web or a device for example. Using a try statement to keep code "simple" instead of using if statements to avoid error-prone calls makes code incredibly slower. Restructure your source code to require less try statements.

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

7. Replace Divisions

7. 更换分区

C# is relatively slow when it comes to division operations. One alternative is to replace divisions with a multiplication-shift operation to further optimize C#. The article explains in detail how to make the conversion.

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

REFERENCE

参考