views:

392

answers:

11

Hi

When I'm reading this tutorial I noticed the following performance tip about using structs in C#:

Unless you need reference type semantics, a class that is smaller than 16 bytes may be more efficiently handled by the system as a struct.

I looked for similar question in stackoverflow but I found some questions that talks about performance best practices in ADO.Net, Networking, Streams, not about performance best practices in C# (The language).

I want to add another tip about using the integer types:

The runtime optimizes the performance of 32-bit integer types (Int32 and UInt32), so use those types for counters and other frequently accessed integral variables.

+9  A: 
  1. Strings are Immutable.
  2. Understand the using statement.
  3. Understand Boxing and how Generics help.
  4. Understand how the Garbage Collector works.
  5. Parallel programming in .Net 4.0
  6. Understand how File IO affects performance.

Eric Lippert talks alot about optimization. I would read his blog.
I would check out Jon Skeet's blog also.

Kevin
7: Premature optimization is the root of all evil. Make it work first; if it works with a series of string-appending lines, that's great. If that results in a noticeably slow execution time that you want to improve, you can refactor to use a StringBuilder later.
KeithS
@KeithS: Premature optimisation is a bad thing, but using StringBuilder isn't good just for speed issues. It also makes clear that you intend to change the string you have created. It is a semantically sound choice for plenty of settings.
Matt Ellen
A: 

Avoid boxing and unboxing in loops.

For example instead of ArrayList use List. Generic collections are not only type-safe but are also faster than non-generics when you use them with value-types.

Carlos Muñoz
+2  A: 

Don't use exceptions in non-exceptional circumstances.

Paul Creasey
Meh. While that's *definitely* good practice, they don't really affect real world performance. I remember a long time ago when I tried to make a game in Java2D, that my way to do concurrency was to just catch the exceptions when two threads tried to read from the same `ArrayList` at the same time. And we're talking about many thousands of exceptions per second. Exceptions *seem* really slow when you have the debugger attached, but without it they don't affect performance unless you have some serious bad design (like exception based parallelism..).
JulianR
Not in the same way as IO can, but in the same order of magnitude as failing to understand strings are immutable!
Paul Creasey
+1  A: 

I can name a lot of performance optimizations :

  1. String.Format / StringBuilder for string manipulation as string is immutable.
  2. Inherit IDisposable to write your own code for disposal of objects, so that using statement could be used later.
  3. Do not set local references to null.
  4. Do not create a new exception while you are throw. Use throw than throw ex
  5. Put large objects as WeakReference, which makes it available to GC immediately. http://www.abhisheksur.com/2010/07/garbage-collection-algorithm-with-use.html
  6. Avoid Boxing / Unboxing. Use Generics.

etc.

abhishek
-1 Some of your suggestions are on the right track, but without more context they can be misleading, especially points 3 and 5. "Do not set local references to null" is vague and can be misleading. I think I know what you mean, but it would need a lot more explanation. WeakReferences are only appropriate in rare cases, not for any objects that are large.
Evgeny
Yes. I just put the points. Little more explanation would be worth. Thanks for pointing it out.
abhishek
+11  A: 

Simply: profile.

Every app is different. Taking time to reduce some code to make it "more efficient" is meaningless if that is not a bottleneck in you app. Also - you may even be making things worse if you don't have numbers to support changes.

In most cases IO is the pinch-point, so thinking about IO is a no-brainer. Ditto DB access. But beyond that: measure it.

Marc Gravell
+2  A: 
RoadWarrior
A: 

In many apps, especially web apps, your app spends most of its time hitting a database. (This is not C# specific) Use a profiling tool to ensure that you do not have long running db queries, select good indexes, and use eager-loading where appropriate to cut down the number of database requests you have to make. This is probably the single biggest thing you can do to improve performance of an app that uses a database, C# or otherwise.

Doug R
A: 

The Performance analyzer in Visual Studio 2010 is awesome for finding performance bottlenecks fast.

If you have to read a property on a GUI element from a worker thread Invoke is very slow. It is much faster to use the ValueChanged event to store the value in an object that is shared between the GUI and worker thread.

Erwin J.
When are floats 7 times faster than doubles? Even under emulation I wouldn't expect that much speed difference, and modern CPUs almost always have FPUs. Doubles are barely slower than ints; they're almost immeasurably slower than floats.
Gabe
A: 

If you subscribe to an event on object "A" from object "B", be sure to unsubscribe from "B"'s events in "A" before "B" changes, otherwise, "B" may never get GC'd.

Hugo
+1  A: 

Not just in C#, but in any OO language where you are encouraged to make lots of data structure classes, it will probably take some performance tuning and profiling experience to learn this, but keep it simple is more than just a plattitude.

It is essential to minimize the number of classes you have, minimize the redundancy of the data, and especially minimize the use of notification-style updating to try to keep the data consistent.

If different components of the data structure need to be kept consistent with each other, it is better to be able to tolerate temporary inconsistency than to try, through notifications, to keep things tightly in agreement.

Many of the complications that are put into data structure arise out of a vague but pervasive desire to make it "more efficient", such as cross-linking data structures so that notifications can implement instantaneous updates. Not only does that greatly complicate the code, leading to bugs, but then when you do performance tuning you find out it is those structures that can be the biggest performance-killers.

Mike Dunlavey
A: 

Avoid string operations where possible (lookups, .Contains("blah"), etc.) when doing massive amounts of operations. I have found significant performance enhancements when removing operations like these where possible.

mrnye