CS 1 Fall 2007

Big Idea

Asymptotic Complexity

Monday, October 15, 2007


An important part of understanding a computation is understanding how its running time (or memory size) grows with its inputs. In the previous lecture, we showed how we could reason about program run time and how we could construct equations to predict the run time.

Often, we do not really care about all the details of the equations, but simply their asymptotic growth rate, which is an approximation to the rate at which a function of some variable grows as the size of the input to the function is increased. This lets us understand how a program may slow down for very large inputs (e.g. when we double the size of the input, will the run time stay the same, increase by a constant amount, double in size, quadruple in size, or increase by an even larger amount?). This will be very important for just about any large scale computation you might want to perform. For instance, when I double the number of atoms in my electrodynamics simulation, how does the run time and memory requirements of my program increase? How about when I double the number of amino acids in my protein folding simulation? Or double the number of bodies in my gravitational simulation? Or double the number of components in my electrical circuit simulation? etc. etc.

Consequently, as an approximate way to quantify the computational requirements of algorithms, computer programmers and computer scientists often focus on the asymptotic complexity of an algorithm -- that is, the growth rate of the dominant term for large values of the input. We ignore all lower order terms and we also ignore any constant scaling factors. So, if we calculate a run time expression like: Time = 12*N3+53*N2+1132*N + 23467, we know that the N3 term will ultimately dominate the run time for large enough inputs, so we say this run time is O(N3) (pronounced "big-oh of N cubed"). Since we often simply want to know the asymptotic run time, this also allows us to save work and avoid calculating the lower order terms (e.g. once we see there is an N3 term, we don't need to account for the size of the N2 terms; we simply need to make sure there is not an N4 term...or any term larger than N3).

In some sense, this is like focusing on getting the order of magnitude right in a physical calculation. It certainly doesn't matter how many decimal places you get correct if you can't get the right order of magnitude -- and for many problems, knowing the order of magnitude is the main thing that matters. For many computer algorithms, the asymptotic effects begin to dominate for modest size applications, and once they do dominate, they tell us most of what we need to know about how the behavior of a program scales with the size of its inputs.