Posted on 4/17/2009 3:10:04 PM by Justin Etheredge
Making code run faster is fun. No no, it is more than fun, it is down right addictive. Very few things in this world are more satisfying that sitting down in front of a slow piece of code and making it run even 10% faster. Even better if you can squeeze an order-of-magnitude increase out of it. Ever sat down in front of a piece of code and sped it up 2 times? 5 times? 10 times? If you haven't then you probably haven't really lived. At least not as a programmer anyways.
But there has to be a limit to the madness. Sure, you don't want to write inefficient code. You want your code to be as fast as possible without expending any extra effort. But what happens when people start making up rules like using "" instead of String.Empty? I'm not arguing one way over the other, I'm not going to tell you that "" looks more readable than String.Empty or vice versa.
Edit: And I'm not here to bust on this article either. As the author pointed out in a comment below, he is merely answering a question about differences between the two, not making up rules or recommendations. End Edit.
The author makes a few valid points about strings in switch statements (even though I'm not a big fan of switch statements, yuck!) and at the end of the article the author shows some performance numbers. String.Empty took 637ms while "" took only 319ms! Oh my! String.Empty is two times slower than ""! Two times! And then you close the browser, leave the article, and decided that never again in your life will you ever use String.Empty again. And on top of that, you will ridicule anyone who does.
Well, you know what I say to that? 1000000000. Let me reformat that, cause it might be hard to read. 1,000,000,000. Or for my European friends 1.000.000.000. Yep 1 billion iterations. That means that each String.Empty comparison took about 0.000000000637 seconds to complete, versus "" that took about 0.000000000319 seconds each. Oooooooooooh noooooooooo! That is just about enough time for light to travel one foot. Bravo.
You do realize that "foreach" versus "for" probably has about the same speed implications that this does, right? Are you going to mandate that your developers only use "for" loops? A lot of the Linq methods are also much slower than their iterative counterparts, so are you going to keep doing filtering in a loop instead of just using the "Where" method? I hope that your answers to these questions are "no". Although I have actually worked somewhere that forbid the use of "foreach". No one paid attention to that rule though.
Here is my list of silly recommendations I have seen that can make code harder to read or modify:
- Use "for" instead of "foreach" – I love variables with tiny names... i, j, k, l.... yum.
- Prefer collections over using Linq – Mmmmmm... I love writing grouping, sorting, and filtering code manually.
- Set every variable to null after using it – If I just give the garbage collector a tiny boost...
- Use "String.length == 0" instead of using String.Empty or "" – Not exactly expected, but not the worst.
- Always use arrays instead of lists – Hmmmm, how often do I actually know the length of a collection ahead of time? Oh, maybe I'll just make it real big!
- Unroll short loops – Am I the compiler?
- Use multiply and shift instead of division – Wow, this is just ridiculous.
- Pull upper-bound of "for" loop into a local variable - really? I thought that if I stopped using foreach that would be enough. Maybe I should just rewrite it in assembler.
- Use sealed classes - Nothing like a sealed class to really fix my app's performance.
- Use non-virtual methods – It was all those virtual table lookups that really did that website in.
- Use StringBuilder for everything! - Who cares how long and ugly the code is?
- Minimize method calls - I've seen some people who follow this one, 5000 line methods anyone?
- Prefer public fields to properties – That darn method call overhead. Every millisecond counts!
I always found it funny how many people who will quote many of these rules will turn around and write some giant grotesque piece of code which uses reflection heavily. But somehow the performance of that piece is nothing to worry about! (And no, for the most part, responsibly used reflection isn't often a problem)
So next time that you are going to start recommending that developers do silly coding practices that can really hurt the readability of your code, you should instead promote clean-coding practices and then do like my friend Simone did, and get some performance numbers so that you know where you need to tweak.
And don't get me wrong, performance is important, and you should always be testing your performance and looking for ways to improve it. Just don't start suffering application maintainability for performance when you don't actually need it. If you are writing business applications then chances are that your data access is about a thousand times slower than anything your application is doing.
If you are building web applications, then you should go down this list for ideas on how to optimize your application:
- Caching
- Caching
- Caching
- Caching
That is all.
P.S. If you want to take away one thing from this post, it is that in the hierarchy of what you should care about in your code, in most cases, performance shouldn't be at the top. That place should be reserved for readability or maintainability.