Search:
Locator+ Code:
FTPOnline Channels Conferences Resources Hot Topics Partner Sites Magazines About FTP RSS 2.0 Feed

Back to VSLive! San Francisco Show Daily Home

email article
printer friendly


Interlocked vs. Lock
Improve overall assembly performance.
by Richard Hale Shaw

VSLive! San Francisco, March 24, 2004

Note: Richard Hale Shaw is presenting "Get Ready for Whidbey: Best Practices for Creating Powerful but Effective Classes, Properties, and Methods in C#" at VSLive! San Francisco on Thursday, March 25. These best practices are from that session.

In my session, I'll show a variety of techniques for improving the quality of your programs. That quality isn't limited to ways you can simplify and streamline your source code; it includes techniques that—if consistently applied—will improve the overall performance of your assemblies as well. A simple example of this is the difference between the C# lock keyword, and the use of the Interlocked.Increment() method (found in System.Threading). You probably already know that you can use lock to create synchronized access by multiple threads to a block of code:

int _counter = 0;
...
lock(this)
	_counter++;

And that the generated intermediate language (IL) will generate the equivalent of this C# code:

System.Threading.Monitor.Enter();
...
try
{
	_counter++;
}
finally
{
	...
	System.Threading.Monitor.Exit();
}

The point is that only one thread at a time can execute the protected code.

You might not be aware that to increment a value in a thread-safe fashion, another—and more efficient—solution at run time is to call Interlocked.Increment():

System.Threading.Interlocked.Increment(ref _counter);

In other words, if you're protecting a large block of code with a number of operations from collisions by multiple threads, lock is probably the best solution. But if you're simply incrementing, decrementing, or exchanging values and need thread safety as well, then using members of the Interlocked class will be simpler—and faster.

How much faster? In some of my informal tests, code that incremented a value with thread safety ran 57 percent faster using Interlocked.Increment() vs. lock. And those who understand programming optimizations know that performance gains generally aren't picked up in huge sweeping algorithmic rewrites, but by many small, incremental changes—introduced at the margin.

ADVERTISEMENT

You can also pick up performance gains in other areas such as Generics in C# 2.0, which will be introduced with the Whidbey release. When using Generics with reference types—and a type-safe version of System.Collections.ArrayList (which is not part of Whidbey, but which I've built from the Rotor sources and will introduce during my Generics in C# session)—I found that using Generics can improve performance of IList.Add and IList.Remove operations by 80 percent. (For example, the Generic version runs in about 1/5 the time of the non-Generic version.) And using value types, these Generic operations ran 30 to 60 percent faster than their non-Generic counterparts.

The point is: Consider isolating your general-purpose classes now (the ones that use object because they need to work with any data type), in preparation for reworking them with Generic implementations later. You'll be glad you did.

About the Author
Richard Hale Shaw, a Microsoft MVP for Visual C#, is the founder of the Richard Hale Shaw Group, which has mentored, consulted, and trained software developers since 1993. He's the chair of C# Live! at the VSLive! San Francisco conference, and the author of The .NET BootCamp, a 5-day, 12-hour-a-day intensive, hands-on training class on .NET programming in C#. Richard specializes in consulting and mentoring on .NET programming in C# and migrating COM/COM+/C++ applications to managed code. You can reach him at http://www.RichardHaleShawGroup.com.

Back to top



Java Pro | Visual Studio Magazine | Windows Server System Magazine
.NET Magazine | Enterprise Architect | XML & Web Services Magazine
VSLive! | Thunder Lizard Events | Discussions | Newsletters | FTP Home