You're getting really good answers here.
The stack* forums are an excellent source of information.
While each language has performance tricks, the key to good performance is simplicity of design.
Then, after the software is running (not when you're coding) deal with performance.
It's unproductive to go eyeballing code and guessing if you should use trick X in location Y.
Let the actual running program tell you what to fix.
(Everybody knows that, but they still use the ready-fire-aim method.)
If you learn this technique for performance diagnosis, you will find it useful, as have many others.
Basically, you interrupt the program at random several times, and each time understand in detail what it's doing.
Understand what it's doing and why.
If you see it doing something twice, no matter how you describe it, that activity is taking significant time.
The sooner you see it, the more significant it is.
Technically, if some activity is consuming fraction p of time, the average number of samples you need before you see it twice is 2/p.
So if p is 20%, on average it will take 10 samples to see it twice.
(Technically, this comes from the negative binomial distribution, where if a coin has fairness p, the number of tails you will get before x heads is, on average, x(1-p)/p.)
The point of this approach is that, rather than measuring various things and hoping to narrow in on some problem code, it shows you the problem in crystal-clear detail, even if it's not localized to a particular piece of code.
It can find problems you can't find any other way.