I've spent the last few days deep in .NET tuning trying to squeeze some extra performance out of a relatively simple loop of webservice calls. I wrote integration tests to time various numbers of worker threads making various numbers of web service calls. I quickly discovered a few interesting points.
Above 5 or so worker threads (on my dual core laptop), the overall time to execute all webservice calls goes up or does not improve. This underscores the fact that a computer can only do so much work. Multithreading gives the appearance of doing work simultaneously, and on multi-cpu machines actually does do work simultaneously, but spinning up a new thread for every activity is generally a bad idea. Each thread has some overhead in terms of memory and processor usage, so using too many can be worse than not using enough. Use the ThreadPool.QueueUserWorkItem or Async methods (which in turn use the ThreadPool) for common threading tasks.
Even with the above practice, it looked like there were still some bottlenecks. A post on to StackOverflow led me to look at 'maxConnections'. Apparently, as .NET pools TCP connections, they deliberately limit apps to 2 active connections (I assume per process) . Microsoft recommends setting this to 12 times the number of CPUs. I set it to 24 and instantly doubled the speed of my tests. Setting it higher did not improve things.
That's pretty impressive bump for 5 lines of configuration. They offer up some additional configuration adjustments to tune your app or server, but these did not apply in my scenario (ie, not in ASP.NET).