For over a year in 2008 through 2010, I led a performance optimisation effort of a small team at a very large client on a shockingly complex e-commerce solution. We profiled the codebase, optimised the environment, implemented code optimisations, and worked to get them in our test environments.
One lesson that stands out from that is that you should never optimise code without evidence that it is a bottleneck. Run a profile, analyse the hot-path, and then (most likely) cache the result of the operation or find a smarter algorithm to accomplish the same task.
I had a colleague on my current project raise a concern about the performance of UTC to Local time conversion. I dismissed it as arithmetic, but he persisted. So we tested it and measured it at our volume as taking 34 milliseconds. For some applications that might be a concern, but not for ours.
Bottlenecks usually involve moving data over a network, or naïve algorithms that are O(c^n) or O(n!) on moderate to large datasets. (Remember that in-memory Linq statements are really just expressive foreach loops, I’ve been burned by that before.)
In general, however, it’s best to write readable and maintainable code. Hacking an algorithm because you think it might be slow (like worrying about time zone conversion) is a poor reason to make a decision on how to design your solution. Gather some evidence. Premature optimisation is the root of all evil.