next up previous contents
Next: Complexity classes Up: How to measure efficiency Previous: What to measure/count   Contents

Some common complexity classes

Very often we are not interested in the actual function that describes the (time) complexity of an algorithm, but just in its complexity class. This basically tells us about the growth of the complexity function, and therefore something about the performance of the algorithm on large numbers of items.

Before we define complexity classes in a more formal manner, let us first gain some intuition for what they actually mean. For this purpose, we choose one function as representative for the classes we wish to consider. We shall see in the next section to which degree a representative can be considered `typical' for its class. (Recall that we are considering functions which map natural numbers (the size of the problem) to the set of real numbers  $ \mathbb{R}$.)

The most common classes (in rising order) are the following:

As a representative, we choose the function which gives the class its name--ie. for $ O(n)$ we choose the function $ n\longmapsto n$, also written as $ f(n)=n$, and for $ O(\log{n})$ we choose $ n\longmapsto \log{n}$, also written as $ f(n)=\log{n}$ (this is the logarithm to base $ 2$). So assume we have algorithms with these functions describing their complexity. In the table below we list how many operations it will take them to deal with a problem of a given size.

$ f(n)$ $ n=2$ $ n=16$ $ n=256$ $ n=1024$ $ n=1048576$
$ 1$ $ 1$ $ 1$ $ 1$ $ 1.0\times 10^0$ $ 1.0\times 10^0$
$ \log{\log{n}}$ 01 $ 2$ $ 3$ $ 3.32\times 10^0$ $ 4.32\times
10^0$
$ \log{n}$ $ 1$ $ 4$ $ 8$ $ 1.00\times 10^1$ $ 2.00\times 10^1$
$ n$ $ 2$ $ 16$ $ 2.56\times 10^2$ $ 1.02\times 10^3$ $ 1.05\times 10^6$
$ n\log{n}$ $ 2$ $ 64$ $ 2.05\times 10^3$ $ 1.02\times 10^4$ $ 2.10\times 10^7$
$ n^2$ $ 4$ $ 256$ $ 6.55 \times 10^4$ $ 1.05\times 10^6$ $ 1.10\times 10^{12}$
$ n^3$ $ 8$ $ 410$ $ 1.68\times 10^7 $ $ 1.07\times 10^9$ $ 1.15\times 10^{18}$
$ 2^n$ $ 4$ $ 65536$ $ 1.16\times 10^{77}$ $ 1.80\times 10^{308}$ $ 6.74\times 10^{315652}$
1 Obviously, this doesn't make sense as a complexity, and for this problem size we would have to make an exception.


These numbers get so big that it is somewhat difficult to decide just how long a time span they would describe. Hence here's a table which gives time spans rather than instruction counts, based on the assumption that we have a computer which can operate at a speed of $ 1$ MIP, where one MIP = a million instructions per second.

$ f(n)$ $ n=2$ $ n=16$ $ n=256$ $ n=1024$ $ n=1048576$
$ 1$ $ 1$ $ \mu$sec1 $ 1$ $ \mu$sec $ 1$ $ \mu$sec $ 1$ $ \mu$sec $ 1$ $ \mu$sec
$ \log{\log{n}}$   $ 2$ $ \mu$sec $ 3$ $ \mu$sec $ 3.32$ $ \mu$sec $ 4.32$ $ \mu$sec
$ \log{n}$ $ 1$ $ \mu$sec $ 4$ $ \mu$sec $ 8$ $ \mu$sec $ 10$ $ \mu$sec $ 20$ $ \mu$sec
$ n$ $ 2$ $ \mu$sec $ 16$ $ \mu$sec $ 256$ $ \mu$sec $ 1.02$ msec2 $ 1.05$ sec
$ n\log{n}$ $ 2$ $ \mu$sec $ 64$ $ \mu$sec $ 2.05$ msec $ 1.02$ msec $ 21$ sec
$ n^2$ $ 4$ $ \mu$sec $ 256$ $ \mu$sec $ 65.5$ msec $ 1.05$ sec $ 1.8$ wks
$ n^3$ $ 8$ $ \mu$sec $ 4.1$ msec $ 16.8$ sec $ 17.9$ min $ 36,559$ yrs
$ 2^n$ $ 4$ $ \mu$sec $ 65.5$ msec $ 3.7\times 10^{63}$ yrs $ 5.7\times 10^{294}$ yrs $ 2.1\times 10^{315639} yrs$3
1 $ 1$ $ \mu$sec is one millionth of a second, or one microsecond
2 $ 1$ msec is one thousandth of a second, or one millisecond
3 This is an extremely long period of time. Current estimates say that the sun will burn out in another $ 5\times 10^{9}$ years. And, of course, we don't have any computers these days which are likely to run uninterrupted for even a single year.


As we can see, if the size of our problem gets really big, there is a huge difference in the time it takes to perform an algorithm of a given class. This is why complexity classes are so important--they tell us how feasible it is to run a program with a big number of data items. Typically, people do not worry much about complexity below the sizes of $ 10$ or maybe $ 20$, but the above numbers should tell you why it is worth thinking about complexity classes where bigger applications are concerned.

Another useful way of thinking about growth classes is thinking about what happens if the problem size doubles. These considerations are given in the following table:

$ f(n)$ If the size of the problem doubles then $ f(n)$ will be  
$ 1$ the same, $ f(2n) = f(n)$
$ \log\log n$ almost the same, $ (\log(\log(2n)) = \log(\log(n) + 1)$;
$ \log n$ more by $ 1=\log 2$, $ f(2n) = f(n) + 1$;
$ n$ twice as big as before, $ f(2n) = 2f(n)$;
$ n \log n$ a bit more than twice as big as before, $ 2n\log(2n) =
2(n\log n) + 2n$;
$ n^2$ four times as big as before, $ f(2n) = 4f(n)$;
$ n^3$ nine times as big as before, $ f(2n) = 8f(n)$;
$ 2^n$ the square of what it was before, $ f(2n) = (f(n))^2$.


We now give a plot of some of the functions from the table. Note that although these functions are only defined on natural numbers, we draw them as if they were defined for all real numbers, because that makes it easier to take in the information presented.

\epsfig{file=figs/plot2-1.eps}

\epsfig{file=figs/plot2-2.eps}


next up previous contents
Next: Complexity classes Up: How to measure efficiency Previous: What to measure/count   Contents
Martin Escardo 2005-01-11