Compiler optimization is generally implemented using a sequence of "optimizing transformations", algorithms which take a program and transform it to produce a semantically equivalent output program that uses fewer resources and/or executes faster. It has been shown that some code optimization problems are NP-complete, or even undecidable. In practice, factors such as the programmer's willingness to wait for the compiler to complete its task place upper limits on the optimizations that a compiler might provide. Optimization is generally a very CPU- and memory-intensive process. In the past, computer memory limitations were also a major factor in limiting which optimizations could be performed.