Optimization can sometimes be difficult, but it is definitely one of the most exciting areas in game development. With some careful planning, lots of coffee, and patience, you can dramatically improve code performance. Multiplying performance is often possible, making the unplayable become interactive. However, there are two key factors to successful optimization.
First, you need to learn to write efficient code as early in the coding process as possible and avoid waiting until the very end to actually profile your code. Monitoring your code every now and then, and taking timings to keep track of performance is a good way to make sure your code is relatively decent from day one. Writing "quick and dirty" solutions and trying to optimize them at the end of the development process is a bad idea. The task will become too daunting, and you will definitely get lost in the details.
Notice, however, that many optimization techniques make code less readable and harder to understand. Donald Knuth once said, "Early optimization is the root of all evil," and he was quite right. Focusing on extreme optimizations early on will surely degrade code clarity and elegance for the sake of raw speed. Pure optimization must thus be left for the end of the coding process. But writing code modules so they are more or less efficient from day one is the best way to ensure deadlines are met and performance evolves as expected. A final, raw optimization phase will make sure those mission-critical components are as efficient as possible.
Second, know your code. Analyze your code and understand what it does, and you will discover new ways to make it run faster. Optimizing code requires a deep understanding of your code's functionality and design. You must have this understanding in order to be able to make decisions that improve performance while maintaining the same great playing experience. You must deeply understand the cost breakdown of each routine from both a time and memory standpoint.