The Definition of ``on the Order of''

It is time to introduce a rigorous description of the phrase ``on the order of'' and to explain why it is acceptable to ignore some constants. Any serious programmer must be thoroughly familiar with this notion. It is the most fundamental method for analyzing and comparing the behavior of programs. This intermezzo provides a first glimpse at the idea; a second course on computing usually provides some more in-depth considerations.

#picture38175#

<#38186#>Figure: A comparions of two running time expressions<#38186#>


Let's consider a sample ``order of'' claim with concrete examples before we agree on a definition. Recall that a function <#67016#><#38188#>F<#38188#><#67016#> may require on the order of <#38189#>N<#38189#> steps and a function <#67017#><#38190#>G<#38190#><#67017#> #tex2html_wrap_inline73858# steps, even though both compute the same results for the same inputs. Now suppose the basic time constants are <#67018#><#38191#>1000<#38191#><#67018#> for <#67019#><#38192#>F<#38192#><#67019#> and 1 for <#67020#><#38193#>G<#38193#><#67020#>. One way to compare the two claims is to tabulate the abstract running time:

#tabular38195#

At first glance the table seems to say that <#67023#><#38202#>G<#38202#><#67023#>'s performance is better than <#67024#><#38203#>F<#38203#><#67024#>'s, because for inputs of the same size (<#38204#>N<#38204#>), <#67025#><#38205#>G<#38205#><#67025#>'s running time is always smaller than <#67026#><#38206#>F<#38206#><#67026#>'s. But a closer look reveals that as the inputs get larger, <#67027#><#38207#>G<#38207#><#67027#>'s advantage decreases. Indeed, for an input of size 1000, the two functions need the same number of steps, and thereafter <#67028#><#38208#>G<#38208#><#67028#> is always slower than <#67029#><#38209#>F<#38209#><#67029#>. Figure~#figbigoh#38210> compares the graphs of the two expressions. It shows that the linear graph for #tex2html_wrap_inline73864# dominates the curve of #tex2html_wrap_inline73866# for some finite number of points but thereafter it is below the curve. The concrete example recalls two important facts about our informal discussion of abstract running time. First, our abstract description of running time is always a claim about the relationship between two quantities: the size of the input and the number of natural recursions evaluated. More precisely, the relationship is a (mathematical) function that maps an abstract size measure of the input to an abstract measure of the running time. Second, when we compare ``on the order of'' properties of functions, such as

#displaymath73868#

we really mean to compare the corresponding functions that consume <#38212#>N<#38212#> and produce the above results. In short, a statement concerning the order of things compares two functions on natural numbers (<#67030#><#38213#>N<#38213#><#67030#>). The comparison of functions on <#67031#><#38214#>N<#38214#><#67031#> is difficult because they are infinite. If a function <#38215#>f<#38215#> produces larger outputs than some other function <#38216#>g<#38216#> for all natural numbers, then <#38217#>f<#38217#> is clearly larger than <#38218#>g<#38218#>. But what if this comparison fails for just a few inputs? Or for a 1,000 such as the one illustrated in figure~#figbigoh#38219>? Because we would still like to make approximate judgements, programmers and scientists adapt the mathematical notion of comparing functions up to some factor and some finite number of exceptions.

<#67032#><#38221#>ORDER-OF (BIG-O)<#38221#><#67032#>: Given a function g on the natural numbers, O(g) (pronounced: ``on the order of g'' or ``big-O of g'') is a class of functions on natural numbers. A function <#38222#>f<#38222#> is in O(g) if there exist numbers <#38223#>c<#38223#> and <#38224#>bigEnough<#38224#> such that for all #tex2html_wrap_inline73880#, it is true that #tex2html_wrap_inline73882#
Recall the performance of <#38227#>F<#38227#> and <#38228#>G<#38228#> from above. For the first, we assumed that it consumed time according to the following function

#displaymath73884#

the performance of second one obeyed the function <#38229#>g<#38229#>:

#displaymath73886#

Using the definition of big-O, we can say that <#38230#>f<#38230#> is O(g), because for all #tex2html_wrap_inline73890#,

#displaymath73892#

which means #tex2html_wrap_inline73894# and c = 1. More importantly, the definition of big-O provides us with a shorthand for stating claims about a functions running time. For example, from now on, we say <#67033#><#38232#>how-many<#38232#><#67033#>'s running time is O(N). Keep in mind that <#38233#>N<#38233#> is the standard abbreviation of the (mathematical) function g(N) = N. Similarly, we can say that, in the worst case, <#67034#><#38234#>sort<#38234#><#67034#>'s running time is #tex2html_wrap_inline73902# and <#67035#><#38235#>max<#38235#><#67035#>'s is #tex2html_wrap_inline73904#. Finally, the definition of big-O explains why we don't have to pay attention to specific constants in our comparsions of abstract running time. Consider <#67036#><#38236#>max<#38236#><#67036#> and <#67037#><#38237#>max2<#38237#><#67037#>. We know that <#67038#><#38238#>max<#38238#><#67038#>'s worst-case running time is in #tex2html_wrap_inline73906#, <#67039#><#38239#>max2<#38239#><#67039#>'s is in O(N). Say, we need the maximum of a list with 10 numbers. Assuming <#67040#><#38240#>max<#38240#><#67040#> and <#67041#><#38241#>max2<#38241#><#67041#> roughly consume the same amount of time per basic step, <#67042#><#38242#>max<#38242#><#67042#> will need #tex2html_wrap_inline73910# steps and <#67043#><#38244#>max2<#38244#><#67043#> will need 10 steps, which means <#67044#><#38245#>max2<#38245#><#67044#> will be faster. Now even if <#67045#><#38246#>max2<#38246#><#67045#>'s basic step requires twice as much time as <#67046#><#38247#>max<#38247#><#67046#>'s basic step, <#67047#><#38248#>max2<#38248#><#67047#> is still around 50 times faster. Futhermore, if we double the size of the input list, <#67048#><#38249#>max<#38249#><#67048#>'s apparent disadvantage totally disappears. In general, the larger the input is, the less relevant are the specific constants.
<#38252#>Exercise 29.2.1<#38252#> In the first subsection, we stated that the function #tex2html_wrap_inline73912# belongs to the class #tex2html_wrap_inline73914#. Determine the pair of numbers c and <#38254#>bigEnough<#38254#> that verify this claim.~ external Solution<#67049#><#67049#> <#38260#>Exercise 29.2.2<#38260#> Consider the functions #tex2html_wrap_inline73918# and #tex2html_wrap_inline73920#. Show that <#38262#>g<#38262#> belongs to O(f), which means that <#38263#>f<#38263#> is abstractly speaking more (or at least equally) expensive than <#38264#>g<#38264#>. If the input size is guaranteed to be between 3 and 12, which function is better?~ external Solution<#67050#><#67050#> <#38270#>Exercise 29.2.3<#38270#> Compare #tex2html_wrap_inline73924# and #tex2html_wrap_inline73926#. Does f belong to O(g) and/or g to O(f)?~ external Solution<#67051#><#67051#>