原文:http://www.dotnetperls.com/optimization

Generally, using the simplest features of the language provides the best performance. For example, using the for-loop and avoiding parameters and return values is typically fastest. We balance these performance goals with readability.

Further:It is best to focus on the "hot paths" in your program for optimizations. Don't emphasize code that is rarely run.

Benchmark.
At all levels of performance optimization, you should be taking
measurements on the changes you make to methods. You can do this with
the .NET Framework methods available in the Stopwatch type.Stopwatch

Tip:It often pays to create console programs where the methods are benchmarked repeatedly on data as it changes.

Benchmark

Note:You should always avoid regressing performance unless there is a clear reason to do so.

 

Static methods.
Non-inlined instance methods are always slower than non-inlined static
methods. To call an instance method, the instance reference must be
resolved, to determine what method to call. Static methods do not use an
instance reference.

If you look at the intermediate language, you will see that static methods can be invoked with fewer instructions. You can see an experiment based on the callvirt and call instructions on this site.IL: callvirt
Arguments.
When you call any method that was not inlined, the runtime will
actually physically copy the variables you pass as arguments to the
formal parameter slot memory in the called method. This causes stack
memory operations.

Therefore:It is faster to minimize arguments, and even use constants in the called methods instead of passing them arguments.

Locals.
When you call a method in your C# program, the runtime allocates a
separate memory region to store all the local variable slots. This
memory is allocated on the stack even if you do not access the variables
in the function call.

Tip:You can call methods faster if they have fewer variables in them. Sometimes we can reuse the same variable.

One way
to do this is to isolate rarely used parts of methods in separate
methods. This makes the fast path in the called method more efficient,
which can have a significant performance gain.Arithmetic Optimization

Also:Often you can use a local variable to copy in a field. Then you can avoid accessing the field—by only changing the local.

Local Variable Field
Constants.
Constants are not assigned a memory region, but are instead considered
values. Therefore, you can never assign a constant, but loading the
constant into memory is more efficient. It is injected directly into the
instruction stream.

And:This eliminates any memory accesses outside of the memory, improving locality of reference.

ReadonlyConst
Static fields.
Static fields are faster than instance fields, for the same reason that
static methods are faster than instance methods. When you load a static
field into memory, you do not need the runtime to resolve the instance
expression.

Loading an instance field must have the object instance first resolved. Even in an object instance, loading a static field is faster because no instance expression instruction is ever used.Static Field
Inline.
Until .NET 4.5, the C# language had no ability to suggest a method be
inlined into its enclosing method call spots. And the .NET Framework is
often conservative. It will not inline medium-sized or large methods.

However:You can manually paste a method body into its call spot. Typically, this improves performance in micro-benchmarks.

Also:It is easy to do. But it will make code harder to modify. It is only suggested for a few critical spots in programs.

Inline Optimization

Tip:In .NET 4.5, the AggressiveInlining enum was introduced. This tells the compiler to inline if possible.

AggressiveInlining
Switch.
You will find that the switch statement compiles in a different way
than if-statements typically do. For example, if you use a switch on an
int, you will often get jump statements, which are similar to a computed
goto mechanism.

Note:Using jump tables makes switches much faster than some if-statements. Also, using a char switch on a string is fast.

If vs. SwitchSwitch
Flatten arrays.
Using two-dimensional arrays is relatively slow. You can explicitly
create a one-dimensional array and access it through arithmetic that
supposes it is a two-dimensional array. This is sometimes called
flattening an array.

Then:You must use multiplication and addition to acquire the correct element address. This optimization often improves performance.

Flatten Array
Jagged arrays.
Flattened arrays are typically most efficient. But they are
impractical. You can use jagged arrays to improve the lookup
performance. The .NET Framework enables faster accesses to jagged arrays
than to 2D arrays.Jagged Arrays

Caution:Jagged arrays may cause slower garbage collections—each jagged array element is treated separately by the garbage collector.

StringBuilder.
If you are doing significant appending of strings using the C#
language, the StringBuilder type can improve performance. This is
because the string type is immutable and can not be changed without
reallocating the entire object.
Sometimes, using
strings instead of StringBuilder for concatenations is faster. This is
typically the case when using small strings or doing infrequent appends.
With most loops, StringBuilder is the better choice.StringBuilderStringBuilder Optimization
Char arrays.
Using char arrays is sometimes the fastest way to build up a string.
Typically, we combine char arrays with for-loops and character testing
expressions. This logic is more painful to develop, but the time savings
can be significant.Char Array
Byte arrays.
In the C# language, the smallest unit of addressable storage is the
byte type. You can store ASCII characters in a single byte, as well as
small numbers. If you can store your data in an array of bytes, this
allows you to save memory.Byte Array
For example,
an array of characters or a string uses two bytes per character. An
array of bytes can represent that data in one byte per character. This
results in about half the total memory usage.ASCII Strings
Arrays.
We have many options for collections, such as the List or ArrayList.
These types are convenient and should be used when necessary. But it is
always more efficient to use a simple array if this is possible.

Note:Complex collections such as List and Dictionary are actually composed of internal arrays.

And:They
add logic to avoid the burden of managing the array size on each use.
But if you do not need this logic, an array is faster.

Arrays
Capacity.
For collections, you can use an optional capacity argument to influence
the initial buffer sizes. It is best to pass a reasonable parameter
when creating a Dictionary or List. This avoids many allocations when
adding elements.Capacity
Rewrite loops.
You can rewrite loops to improve performance. The foreach-loop has good
performance in many cases. But it is best to use the for-loop in all
performance-critical sections when possible.

Note:For-loops sometimes have better raw performance. And you can often reuse the index variable to optimize elsewhere.

Typically,
the while-loop, the for-loop and the do-while loop have the best
performance. Also, it is sometimes beneficial—and sometimes harmful—to
"hoist" the maximum loop variable outside of the for-loop statement.For vs. Foreach
Structs. It is typically best to entirely avoid

structs. If you use structs, you must avoid passing the struct as a parameter to methods. Otherwise, performance may degrade to worse than using a class type.

Note:In the .NET Framework, structs are copied in their entirety on each function call or return value.

Structs
can improve the performance of the garbage collector by reducing the
number of distinct objects. Also, you can sometimes use separate arrays
instead of arrays of structs, which can improve performance further.Struct
Lookup tables.
While switch statements or hashtables can provide good performance,
using a lookup table is frequently the optimal choice. Instead of
testing each character using logic to lowercase, you can translate it
through a lookup table.Char Lookup Table
Also,
the lookup table can be implemented as a character array. Another
example is that you can implement the ROT13 algorithm with a lookup
table, improving performance by more than two times.ROT13
Char argument.
Often, you may need to pass a single character to a method as an
argument. For example, the StringBuilder type allows you to append a
single char. The Response.Write method also allows you to write a single
char.Response.Write

Note:It is more efficient to pass a char instead of a single-char string. We benchmark and show this optimization.

Tip:The char is a value type, and is represented by two bytes, while a string is a reference type and requires over 20 bytes.

StringBuilder Data Types
ToString.
It is poor programming to use the ToString method when it is not
needed. Sometimes, developers will call ToString on a character in a
string, and then test it against a single-character string literal. This
is inefficient.

Instead:Use a character testing expression with two chars. Please reference the specific article on this topic for more details.

String For-Loop

Caution:This mistake sometimes results in code that is ten times slower than the correct approach.

Int string cache.
Many C# programs use the ToString method on integer values frequently.
This requires an allocation on the managed heap for the new string. This
will cause the next garbage collection to become slower.

Tip:You can use a lookup table cache to optimize common cases for the integer ToString operation.

And:This site demonstrates how this lookup table can make the ToString method thirty times faster.

ToString Optimization
IL Disassembler.
For .NET development, open your methods with the IL Disassembler tool
provided by Microsoft. This is a free tool and it provides an interface
to view the MSIL (Microsoft Intermediate Language) output of compiled
Release executables.

Tip:It is sometimes useful to save copies of the intermediate language as you make changes, or to even count instructions.

IL Disassembler
Avoid sorting.
Often, you can avoid performing a sort operation on an array or string
by testing whether the input string or array is already sorted.
Sometimes this makes a big performance improvement. In other cases, this
slows down programs.Alphabetize String
String conversions.
You can actually avoid many string-based conversions. For example, you
may need to ensure that a string is lowercased. If the string is already
lowercase, you can avoid allocating a new string.

However:The Framework ToLower method will not avoid this. You must manually test to see if no lowercasing is necessary.

char.IsLower
Avoid Path.
The Path methods in the System.IO namespace are somewhat slow for many
applications. Sometimes they can cause unnecessary allocations to occur,
copying strings more than once. We can avoid them with character-based
algorithms.Path, Optimization
List Clear.
Avoiding allocations is sometimes (but not always) faster. In some
programs, you can call Clear on a Dictionary to avoid re-creating a new
Dictionary. But in my testing, calling Clear on a List is slow.Clear
Instead,
just re-creating the List is faster. This is because the garbage
collector is more optimized for eliminating old data than the method.
This is not always the case. Experimentation and benchmarking is needed.
Hash.
It is important that you use hashtables in your programs when
appropriate. The Dictionary collection in the .NET Framework is not
optimal in many cases, but provides good performance in many different
situations.Dictionary

Tip:Knowing every detail of the hashtable type, in whatever language you are using, is nearly always a performance advantage.

Learn.
The site you are reading contains a multitude of optimization
experiments, often proven with benchmarks that provide times in
nanoseconds per method call. Resources such as this site are invaluable
for certain tasks in programming.

Note:Before Dot Net Perls came about, no site had this information on optimization. We should learn from each other.

Compiler theory.
Experimentation such as benchmarking and analyzing instructions
generated can result in excellent program performance. But without
understanding the core theories of compilers you may be lacking
knowledge about program performance.

However:Compiler theory involves advanced mathematics and can be dense to start with.

Compiler
My observation
is that few application developers have a significant knowledge of
compiler theory. This topic may be more suitable to academic computer
scientists and not rapid application development programmers.

Tip:You too can slay the dragon with syntax directed translation. The compiler is mightier than the sword.

Temporal locality.
Another way you can optimize a program significantly is by rearranging
it to increase temporal locality. This means that methods that act on a
certain part of memory (such as the hard disk) are run at all once.Temporal Locality
Undecidable.
The term "optimization" is a misnomer in computer science. A program
can never be truly optimized. Because compiler theory is undecidable, a
program can never be proven to be optimally efficient. Perhaps another
approach is faster.

However:One way we improve the situation is by extensively testing. Processors change. Theory only gets us so far.

Secrets.
There are many pages on this website that are focused on optimization
tips. These pages are listed below. Most of them rewrite a certain
pattern of code to something arguably more efficient.Array OptimizationChar LowercaseDecrement OptimizationDictionary OptimizationException Optimizationint.Parse OptimizationInteger AppendMask OptimizationParameter OptimizationReplace OptimizationToString Formats

Tip:Please be aware some of these optimizations result in code that is less maintainable. Not all secrets are useful ones.

Research.
I found many optimization tips (for various languages) in Code
Complete. I recommend this book for some tips. Some of the strategies
may not be useful in managed languages like C#, but many are still
relevant.

Use a high-quality design. Make the program right. Make it
modular and easily modifiable so that it's easy to work on later. When
it's complete and correct, check the performance. If the program
lumbers, make it fast and small. Don't optimize until you know you need
to.

Code Complete
Summary.
There are many optimizations you can make at the level of statements
and methods. External performance factors (including hardware) are more
significant for many programs. But these tips can help in a significant
way.

转 c#性能优化秘密的更多相关文章

  1. Android性能优化系列之apk瘦身

    Android性能优化系列之布局优化 Android性能优化系列之内存优化 为什么APK要瘦身.APK越大,在下载安装过程中.他们耗费的流量会越多,安装等待时间也会越长:对于产品本身,意味着下载转化率 ...

  2. BeagleBone Black Industrial 进阶设置(性能优化以及延长板载eMMC存储寿命)

    前言 原创文章,转载引用务必注明链接.水平有限,欢迎指正. 本文使用markdown写成,为获得更好的阅读体验,推荐访问我的博客原文: http://www.omoikane.cn/2016/09/1 ...

  3. 01.SQLServer性能优化之----强大的文件组----分盘存储

    汇总篇:http://www.cnblogs.com/dunitian/p/4822808.html#tsql 文章内容皆自己的理解,如有不足之处欢迎指正~谢谢 前天有学弟问逆天:“逆天,有没有一种方 ...

  4. 03.SQLServer性能优化之---存储优化系列

    汇总篇:http://www.cnblogs.com/dunitian/p/4822808.html#tsql 概  述:http://www.cnblogs.com/dunitian/p/60413 ...

  5. Web性能优化:What? Why? How?

    为什么要提升web性能? Web性能黄金准则:只有10%~20%的最终用户响应时间花在了下载html文档上,其余的80%~90%时间花在了下载页面组件上. web性能对于用户体验有及其重要的影响,根据 ...

  6. Web性能优化:图片优化

    程序员都是懒孩子,想直接看自动优化的点:传送门 我自己的Blog:http://cabbit.me/web-image-optimization/ HTTP Archieve有个统计,图片内容已经占到 ...

  7. C#中那些[举手之劳]的性能优化

    隔了很久没写东西了,主要是最近比较忙,更主要的是最近比较懒...... 其实这篇很早就想写了 工作和生活中经常可以看到一些程序猿,写代码的时候只关注代码的逻辑性,而不考虑运行效率 其实这对大多数程序猿 ...

  8. JavaScript性能优化

    如今主流浏览器都在比拼JavaScript引擎的执行速度,但最终都会达到一个理论极限,即无限接近编译后程序执行速度. 这种情况下决定程序速度的另一个重要因素就是代码本身. 在这里我们会分门别类的介绍J ...

  9. 02.SQLServer性能优化之---牛逼的OSQL----大数据导入

    汇总篇:http://www.cnblogs.com/dunitian/p/4822808.html#tsql 上一篇:01.SQLServer性能优化之----强大的文件组----分盘存储 http ...

随机推荐

  1. 干掉windows无脑设定:“始终使用选择的程序打开这种文件”、“使用Web服务查找正确的程序”

    先看几张图体会一下: 实在很佩服自己就那样默默忍受了很多很多年.其实这些东西在网上小小的一搜,5分钟就能搞定. 然而我们大家都在想,现在没时间,我还要做xxxx事呢,反正多点两下鼠标而已. 是啊,点两 ...

  2. VS2013创建ASP.NET应用程序描述

    你的 ASP.NET 应用程序 恭喜! 你已创建了一个项目 此应用程序包含: 显示“主页”.“关于”和“联系方式”之间的基本导航的示例页 使用 Bootstrap 进行主题定位 身份验证,如果选择此项 ...

  3. 011_TCP专项研究监控

    (1)In Segs 数据源: /proc/net/snmp; 采集方式:累计值,每10秒采集一次取差值: 指标:net.snmp.tcp (key: system); In Segs: tcp协议层 ...

  4. vue的过滤器filter

    前记: 排版记录,未免太耽误时间,我就简单的来,下面是一个vue 过滤器的写法,demo 演示,限制一个字符串的长度. vue filter 的官网介绍 https://cn.vuejs.org/v2 ...

  5. JavaScript 当月第一天和最后一天

    1. 概述 1.1 说明 在项目过程中,有时候需要默认展示一个月的查询条件,即当月的第一天和最后一天. 2. 代码 2.1 代码示例 直接调用getFirstAndLastDay()即可得到当月的第一 ...

  6. bounding box的简单理解

    1. 小吐槽 OverFeat是我看的第一篇深度学习目标检测paper,因为它是第一次用深度学习来做定位.目标检测问题.可是,很难懂...那个bounding box写得也太简单了吧.虽然,很努力地想 ...

  7. 详解MariaDB数据库的索引

    1.什么是索引 索引是一种特殊的文件(InnoDB数据表上的索引是表空间的一个组成部分),它们包含着对数据表里所有记录的引用指针. 更通俗的说,数据库索引好比是一本书前面的目录,在查找内容之前可以先在 ...

  8. Win10 中将网页转换成pdf的简便方法

    注意:该方法不是将网页完整地保存下来,而是选取其中主要的文字信息. (1)打开要保存的网页 (2)按快捷键 Ctrl+P 打开打印界面 (3)选择打印机为 “Microsoft Print to PD ...

  9. CSS 屏幕大小自适应

    要想实现css屏幕大小自适应,首先得引入 CSS3 @media 媒体查询器: media的使用和规则: ①被链接文档将显示在什么设备上. ②用于为不同的媒介类型规定不同的样式. 语法:  @medi ...

  10. centos下设置开机启动程序

    首先,设置权限, 由于/etc/rc.local是/etc/rc.d/rc.local的软连接,所以必须确保/etc/rc.local和/etc/rc.d/rc.local都有x权限(可执行) 执行命 ...