emacs.d/clones/lisp/htdp.org/2022-8-7/Book/i5-6.html

307 lines
No EOL
126 KiB
HTML

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html><head><meta http-equiv="content-type" content="text/html; charset=utf-8"/><meta name="viewport" content="width=device-width, initial-scale=0.8"/><title>Intermezzo 5: The Cost of Computation</title><link rel="stylesheet" type="text/css" href="scribble.css" title="default"/><link rel="stylesheet" type="text/css" href="shared.css" title="default"/><link rel="stylesheet" type="text/css" href="racket.css" title="default"/><link rel="stylesheet" type="text/css" href="figure.css" title="default"/><link rel="stylesheet" type="text/css" href="manual-style.css" title="default"/><link rel="stylesheet" type="text/css" href="manual-racket.css" title="default"/><script type="text/javascript" src="scribble-common.js"></script><script type="text/javascript" src="figure.js"></script><script type="text/javascript" src="manual-racket.js"></script><!--[if IE 6]><style type="text/css">.SIEHidden { overflow: hidden; }</style><![endif]--></head><body id="scribble-racket-lang-org"><div class="tocset"><div class="tocview"><div class="tocviewlist tocviewlisttopspace"><div class="tocviewtitle"><table cellspacing="0" cellpadding="0"><tr><td style="width: 1em;"><a href="javascript:void(0);" title="Expand/Collapse" class="tocviewtoggle" onclick="TocviewToggle(this,&quot;tocview_0&quot;);">&#9660;</a></td><td></td><td><a href="index.html" class="tocviewlink" data-pltdoc="x">How to Design Programs, Second Edition</a></td></tr></table></div><div class="tocviewsublisttop" style="display: block;" id="tocview_0"><table cellspacing="0" cellpadding="0"><tr><td align="right"></td><td><a href="part_preface.html" class="tocviewlink" data-pltdoc="x">Preface</a></td></tr><tr><td align="right"></td><td><a href="part_prologue.html" class="tocviewlink" data-pltdoc="x">Prologue:<span class="mywbr"> &nbsp;</span> How to Program</a></td></tr><tr><td align="right">I&nbsp;</td><td><a href="part_one.html" class="tocviewlink" data-pltdoc="x">Fixed-<wbr></wbr>Size Data</a></td></tr><tr><td align="right"></td><td><a href="i1-2.html" class="tocviewlink" data-pltdoc="x">Intermezzo 1: Beginning Student Language</a></td></tr><tr><td align="right">II&nbsp;</td><td><a href="part_two.html" class="tocviewlink" data-pltdoc="x">Arbitrarily Large Data</a></td></tr><tr><td align="right"></td><td><a href="i2-3.html" class="tocviewlink" data-pltdoc="x">Intermezzo 2: Quote, Unquote</a></td></tr><tr><td align="right">III&nbsp;</td><td><a href="part_three.html" class="tocviewlink" data-pltdoc="x">Abstraction</a></td></tr><tr><td align="right"></td><td><a href="i3-4.html" class="tocviewlink" data-pltdoc="x">Intermezzo 3: Scope and Abstraction</a></td></tr><tr><td align="right">IV&nbsp;</td><td><a href="part_four.html" class="tocviewlink" data-pltdoc="x">Intertwined Data</a></td></tr><tr><td align="right"></td><td><a href="i4-5.html" class="tocviewlink" data-pltdoc="x">Intermezzo 4: The Nature of Numbers</a></td></tr><tr><td align="right">V&nbsp;</td><td><a href="part_five.html" class="tocviewlink" data-pltdoc="x">Generative Recursion</a></td></tr><tr><td align="right"></td><td><a href="i5-6.html" class="tocviewselflink" data-pltdoc="x">Intermezzo 5: The Cost of Computation</a></td></tr><tr><td align="right">VI&nbsp;</td><td><a href="part_six.html" class="tocviewlink" data-pltdoc="x">Accumulators</a></td></tr><tr><td align="right"></td><td><a href="part_epilogue.html" class="tocviewlink" data-pltdoc="x">Epilogue:<span class="mywbr"> &nbsp;</span> Moving On</a></td></tr></table></div></div><div class="tocviewlist"><table cellspacing="0" cellpadding="0"><tr><td style="width: 1em;"><a href="javascript:void(0);" title="Expand/Collapse" class="tocviewtoggle" onclick="TocviewToggle(this,&quot;tocview_1&quot;);">&#9658;</a></td><td></td><td><a href="i5-6.html" class="tocviewselflink" data-pltdoc="x">Intermezzo 5: The Cost of Computation</a></td></tr></table><div class="tocviewsublistbottom" style="display: none;" id="tocview_1"><table cellspacing="0" cellpadding="0"><tr><td align="right"></td><td><a href="i5-6.html#%28part._.Concrete_.Time__.Abstract_.Time%29" class="tocviewlink" data-pltdoc="x">Concrete Time, Abstract Time</a></td></tr><tr><td align="right"></td><td><a href="i5-6.html#%28part._.The_.Definition_of__.On_the_.Order_.Of_%29" class="tocviewlink" data-pltdoc="x">The Definition of &ldquo;On the Order Of&rdquo;</a></td></tr><tr><td align="right"></td><td><a href="i5-6.html#%28part._.Why_.Do_.Programs_.Use_.Predicates_and_.Selectors_%29" class="tocviewlink" data-pltdoc="x">Why Do Programs Use Predicates and Selectors?</a></td></tr><tr><td align="right"></td><td><a href="i5-6.html#%28part._i5-6-fake%29" class="tocviewlink" data-pltdoc="x"></a></td></tr></table></div></div></div></div><div class="maincolumn"><div class="main"><div class="versionbox"><span class="version">8.6.0.2</span></div><div class="navsettop"><span class="navleft"><div class="nosearchform"></div>&nbsp;&nbsp;<span class="tocsettoggle">&nbsp;&nbsp;<a href="javascript:void(0);" title="show/hide table of contents" onclick="TocsetToggle();">contents</a></span></span><span class="navright">&nbsp;&nbsp;<a href="part_five.html" title="backward to &quot;V Generative Recursion&quot;" data-pltdoc="x">&larr; prev</a>&nbsp;&nbsp;<a href="index.html" title="up to &quot;How to Design Programs, Second Edition&quot;" data-pltdoc="x">up</a>&nbsp;&nbsp;<a href="part_six.html" title="forward to &quot;VI Accumulators&quot;" data-pltdoc="x">next &rarr;</a></span>&nbsp;</div><h3><a name="(part._i5-6)"></a>Intermezzo 5: The Cost of Computation</h3><table cellspacing="0" cellpadding="0"><tr><td><p><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;</span><a href="i5-6.html#%28part._.Concrete_.Time__.Abstract_.Time%29" class="toclink" data-pltdoc="x">Concrete Time, Abstract Time</a></p></td></tr><tr><td><p><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;</span><a href="i5-6.html#%28part._.The_.Definition_of__.On_the_.Order_.Of_%29" class="toclink" data-pltdoc="x">The Definition of &ldquo;On the Order Of&rdquo;</a></p></td></tr><tr><td><p><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;</span><a href="i5-6.html#%28part._.Why_.Do_.Programs_.Use_.Predicates_and_.Selectors_%29" class="toclink" data-pltdoc="x">Why Do Programs Use Predicates and Selectors?</a></p></td></tr><tr><td><p><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;</span><a href="i5-6.html#%28part._i5-6-fake%29" class="toclink" data-pltdoc="x"></a></p></td></tr></table><p><div class="SIntrapara">What do you know about program <span class="RktSym">f</span> once the following tests
succeed:
</div><div class="SIntrapara"><blockquote class="SCodeFlow"><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._check-expect%29%29" class="RktStxLink" data-pltdoc="x">check-expect</a></span><span class="hspace">&nbsp;</span><span class="RktPn">(</span><span class="RktSym">f</span><span class="hspace">&nbsp;</span><span class="RktVal">0</span><span class="RktPn">)</span><span class="hspace">&nbsp;</span><span class="RktVal">0</span><span class="RktPn">)</span></td></tr><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._check-expect%29%29" class="RktStxLink" data-pltdoc="x">check-expect</a></span><span class="hspace">&nbsp;</span><span class="RktPn">(</span><span class="RktSym">f</span><span class="hspace">&nbsp;</span><span class="RktVal">1</span><span class="RktPn">)</span><span class="hspace">&nbsp;</span><span class="RktVal">1</span><span class="RktPn">)</span></td></tr><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._check-expect%29%29" class="RktStxLink" data-pltdoc="x">check-expect</a></span><span class="hspace">&nbsp;</span><span class="RktPn">(</span><span class="RktSym">f</span><span class="hspace">&nbsp;</span><span class="RktVal">2</span><span class="RktPn">)</span><span class="hspace">&nbsp;</span><span class="RktVal">8</span><span class="RktPn">)</span></td></tr></table></blockquote></div><div class="SIntrapara">If this question showed up on a standard test, you might respond with this:
</div><div class="SIntrapara"><blockquote class="SCodeFlow"><p><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._define%29%29" class="RktStxLink" data-pltdoc="x">define</a></span><span class="hspace">&nbsp;</span><span class="RktPn">(</span><span class="RktSym">f</span><span class="hspace">&nbsp;</span><span class="RktSym">x</span><span class="RktPn">)</span><span class="hspace">&nbsp;</span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._expt%29%29" class="RktValLink" data-pltdoc="x">expt</a></span><span class="hspace">&nbsp;</span><span class="RktSym">x</span><span class="hspace">&nbsp;</span><span class="RktVal">3</span><span class="RktPn">)</span><span class="RktPn">)</span></p></blockquote></div><div class="SIntrapara">But nothing speaks against the following:
</div><div class="SIntrapara"><blockquote class="SCodeFlow"><p><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._define%29%29" class="RktStxLink" data-pltdoc="x">define</a></span><span class="hspace">&nbsp;</span><span class="RktPn">(</span><span class="RktSym">f</span><span class="hspace">&nbsp;</span><span class="RktSym">x</span><span class="RktPn">)</span><span class="hspace">&nbsp;</span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._if%29%29" class="RktStxLink" data-pltdoc="x">if</a></span><span class="hspace">&nbsp;</span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._~3d%29%29" class="RktValLink" data-pltdoc="x">=</a></span><span class="hspace">&nbsp;</span><span class="RktSym">x</span><span class="hspace">&nbsp;</span><span class="RktVal">2</span><span class="RktPn">)</span><span class="hspace">&nbsp;</span><span class="RktVal">8</span><span class="hspace">&nbsp;</span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._%2A%29%29" class="RktValLink" data-pltdoc="x">*</a></span><span class="hspace">&nbsp;</span><span class="RktSym">x</span><span class="hspace">&nbsp;</span><span class="RktSym">x</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span></p></blockquote></div><div class="SIntrapara">Tests tell you only that a program works as expected on some inputs.</div></p><p>In the same spirit, timing the evaluation of a program application for
specific inputs tells you how long it takes to compute the answers for
those inputs&#8212;<wbr></wbr>and nothing else.<span class="refelem"><span class="refcolumn"><span class="refcontent">You may also wish to reread
<a href="part_three.html#%28part._sec~3alocal-definitions%29" data-pltdoc="x">Local Definitions</a> and the discussion of integrity checks in
<a href="part_four.html#%28part._db._sec~3aproj-db%29" data-pltdoc="x">Project: Database</a>.</span></span></span> You may have two
programs&#8212;<wbr></wbr><span class="RktSym">prog-linear</span><span class="RktMeta"></span> and <span class="RktSym">prog-square</span><span class="RktMeta"></span>&#8212;<wbr></wbr>that compute the same answers when given
the same inputs, and you may find that for all chosen inputs, <span class="RktSym">prog-linear</span><span class="RktMeta"></span> always
computes the answer faster than <span class="RktSym">prog-square</span><span class="RktMeta"></span>. <a href="part_five.html#%28part._sec~3achoice%29" data-pltdoc="x">Making Choices</a> presents just
such a pair of programs: <span class="RktSym">gcd</span>, a <a name="(idx._(gentag._694))"></a>structurally recursive program,
and <span class="RktSym">gcd-generative</span>, an equivalent but generative-recursive
program. The timing comparison suggests that the latter is much faster
than the former.</p><blockquote class="Figure"><blockquote class="Centerfigure"><blockquote class="FigureInside"><blockquote class="SCentered"><p><img src="pict_237.png" alt="image" width="400" height="400"/></p></blockquote></blockquote></blockquote><p class="Centertext"><span class="Legend"><span class="FigureTarget"><a name="(counter._(figure._fig~3aperformance))" x-target-lift="Figure"></a>Figure&nbsp;176: </span>A comparison of two running time expressions</span></p></blockquote><p>How confident are you that you wish to use <span class="RktSym">prog-linear</span><span class="RktMeta"></span> instead of
<span class="RktSym">prog-square</span><span class="RktMeta"></span>? Consider the graph in <a href="i5-6.html#%28counter._%28figure._fig~3aperformance%29%29" data-pltdoc="x">figure&nbsp;<span class="FigureRef">176</span></a>. In this
graph, the x-axis records the size of the input&#8212;<wbr></wbr>say, the length of
a list&#8212;<wbr></wbr>and the y-axis records the time it takes to compute the
answer for an input of a specific size. Assume that the straight line
represents the running time of <span class="RktSym">prog-linear</span><span class="RktMeta"></span> and the curved graph represents
<span class="RktSym">prog-square</span><span class="RktMeta"></span>. In the shaded region, <span class="RktSym">prog-linear</span><span class="RktMeta"></span> takes more time than
<span class="RktSym">prog-square</span><span class="RktMeta"></span>, but at the edge of this region the two graphs cross, and to
its right the performance of <span class="RktSym">prog-square</span><span class="RktMeta"></span> is worse than that of
<span class="RktSym">prog-linear</span><span class="RktMeta"></span>. If, for whatever reasons, you had evaluated the performance of
<span class="RktSym">prog-linear</span><span class="RktMeta"></span> and <span class="RktSym">prog-square</span><span class="RktMeta"></span> only for input sizes in the shaded region and if
your clients were to run your program mostly on inputs that fall in the
nonshaded region, you would be delivering the wrong program.</p><p>This intermezzo introduces the idea of <span style="font-style: italic">algorithmic analysis</span>,
which allows programmers to make general statements about a program&rsquo;s
performance and everyone else about the growth of a function.
<span class="refelem"><span class="refcolumn"><span class="refcontent">We thank Prabhakar Ragde for sharing his notes on connecting
the first edition of this book with algorithmic analysis.</span></span></span>Any serious
programmer and scientist must eventually become thoroughly familiar with
this notion. It is the basis for analyzing performance attributes of
programs. To understand the idea properly, you will need to work through a
text book.</p><h3><a name="(part._.Concrete_.Time__.Abstract_.Time)"></a>Concrete Time, Abstract Time</h3><p><div class="SIntrapara"><a href="part_five.html#%28part._sec~3achoice%29" data-pltdoc="x">Making Choices</a> compares the running time of <span class="RktSym">gcd</span> and
<span class="RktSym">gcd-generative</span>. In addition, it argues that the latter is better
because it always uses fewer recursive steps than the former to compute
an answer. We use this idea as the starting point to analyze the
performance of <span class="RktSym">how-many</span>, a simple program from
<a href="part_two.html#%28part._ch~3adesign-lists%29" data-pltdoc="x">Designing with Self-Referential Data Definitions</a>: <a name="(idx._(gentag._695))"></a>
</div><div class="SIntrapara"><blockquote class="SCodeFlow"><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._define%29%29" class="RktStxLink" data-pltdoc="x">define</a></span><span class="hspace">&nbsp;</span><span class="RktPn">(</span><span class="RktSym">how-many</span><span class="hspace">&nbsp;</span><span class="RktSym">a-list</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace">&nbsp;&nbsp;</span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._cond%29%29" class="RktStxLink" data-pltdoc="x">cond</a></span></td></tr><tr><td><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="RktPn">[</span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._empty~3f%29%29" class="RktValLink" data-pltdoc="x">empty?</a></span><span class="hspace">&nbsp;</span><span class="RktSym">a-list</span><span class="RktPn">)</span><span class="hspace">&nbsp;</span><span class="RktVal">0</span><span class="RktPn">]</span></td></tr><tr><td><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="RktPn">[</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._else%29%29" class="RktStxLink" data-pltdoc="x">else</a></span><span class="hspace">&nbsp;</span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._%2B%29%29" class="RktValLink" data-pltdoc="x">+</a></span><span class="hspace">&nbsp;</span><span class="RktPn">(</span><span class="RktSym">how-many</span><span class="hspace">&nbsp;</span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._rest%29%29" class="RktValLink" data-pltdoc="x">rest</a></span><span class="hspace">&nbsp;</span><span class="RktSym">a-list</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="hspace">&nbsp;</span><span class="RktVal">1</span><span class="RktPn">)</span><span class="RktPn">]</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr></table></blockquote></div></p><p><div class="SIntrapara">Suppose we want to know how long it takes to compute the length of some
unknown, non-empty list. Using the rules of computation from
<a href="i1-2.html" data-pltdoc="x">Intermezzo 1: Beginning Student Language</a>, we can look at this process as a series of algebraic
manipulations:
</div><div class="SIntrapara"><blockquote class="SCodeFlow"><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td><span class="RktPn">(</span><span class="RktSym">how-many</span><span class="hspace">&nbsp;</span><span class="RktSym">some-non-empty-list</span><span class="RktPn">)</span></td></tr><tr><td><span class="RktSym">==</span></td></tr><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._cond%29%29" class="RktStxLink" data-pltdoc="x">cond</a></span></td></tr><tr><td><span class="hspace">&nbsp;&nbsp;</span><span class="RktPn">[</span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._empty~3f%29%29" class="RktValLink" data-pltdoc="x">empty?</a></span><span class="hspace">&nbsp;</span><span class="RktSym">some-non-empty-list</span><span class="RktPn">)</span><span class="hspace">&nbsp;</span><span class="RktVal">0</span><span class="RktPn">]</span></td></tr><tr><td><span class="hspace">&nbsp;&nbsp;</span><span class="RktPn">[</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._else%29%29" class="RktStxLink" data-pltdoc="x">else</a></span><span class="hspace">&nbsp;</span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._%2B%29%29" class="RktValLink" data-pltdoc="x">+</a></span><span class="hspace">&nbsp;</span><span class="RktPn">(</span><span class="RktSym">how-many</span><span class="hspace">&nbsp;</span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._rest%29%29" class="RktValLink" data-pltdoc="x">rest</a></span><span class="hspace">&nbsp;</span><span class="RktSym">some-non-empty-list</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="hspace">&nbsp;</span><span class="RktVal">1</span><span class="RktPn">)</span><span class="RktPn">]</span><span class="RktPn">)</span></td></tr><tr><td><span class="RktSym">==</span></td></tr><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._cond%29%29" class="RktStxLink" data-pltdoc="x">cond</a></span></td></tr><tr><td><span class="hspace">&nbsp;&nbsp;</span><span class="RktPn">[</span><span class="RktVal">#false</span><span class="hspace">&nbsp;</span><span class="RktVal">0</span><span class="RktPn">]</span></td></tr><tr><td><span class="hspace">&nbsp;&nbsp;</span><span class="RktPn">[</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._else%29%29" class="RktStxLink" data-pltdoc="x">else</a></span><span class="hspace">&nbsp;</span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._%2B%29%29" class="RktValLink" data-pltdoc="x">+</a></span><span class="hspace">&nbsp;</span><span class="RktPn">(</span><span class="RktSym">how-many</span><span class="hspace">&nbsp;</span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._rest%29%29" class="RktValLink" data-pltdoc="x">rest</a></span><span class="hspace">&nbsp;</span><span class="RktSym">some-non-empty-list</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="hspace">&nbsp;</span><span class="RktVal">1</span><span class="RktPn">)</span><span class="RktPn">]</span><span class="RktPn">)</span></td></tr><tr><td><span class="RktSym">==</span></td></tr><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._cond%29%29" class="RktStxLink" data-pltdoc="x">cond</a></span></td></tr><tr><td><span class="hspace">&nbsp;&nbsp;</span><span class="RktPn">[</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._else%29%29" class="RktStxLink" data-pltdoc="x">else</a></span><span class="hspace">&nbsp;</span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._%2B%29%29" class="RktValLink" data-pltdoc="x">+</a></span><span class="hspace">&nbsp;</span><span class="RktPn">(</span><span class="RktSym">how-many</span><span class="hspace">&nbsp;</span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._rest%29%29" class="RktValLink" data-pltdoc="x">rest</a></span><span class="hspace">&nbsp;</span><span class="RktSym">some-non-empty-list</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="hspace">&nbsp;</span><span class="RktVal">1</span><span class="RktPn">)</span><span class="RktPn">]</span><span class="RktPn">)</span></td></tr><tr><td><span class="RktSym">==</span></td></tr><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._%2B%29%29" class="RktValLink" data-pltdoc="x">+</a></span><span class="hspace">&nbsp;</span><span class="RktPn">(</span><span class="RktSym">how-many</span><span class="hspace">&nbsp;</span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._rest%29%29" class="RktValLink" data-pltdoc="x">rest</a></span><span class="hspace">&nbsp;</span><span class="RktSym">some-non-empty-list</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="hspace">&nbsp;</span><span class="RktVal">1</span><span class="RktPn">)</span></td></tr></table></blockquote></div><div class="SIntrapara">The first step is to replace <span class="RktSym">a-list</span> in the definition of
<span class="RktSym">how-many</span> with the actual argument, <span class="RktSym">some-non-empty-list</span>, which
yields the first <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._cond%29%29" class="RktStxLink" data-pltdoc="x">cond</a></span> expression. Next we must evaluate
</div><div class="SIntrapara"><blockquote class="SCodeFlow"><p><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._empty~3f%29%29" class="RktValLink" data-pltdoc="x">empty?</a></span><span class="hspace">&nbsp;</span><span class="RktSym">some-non-empty-list</span><span class="RktPn">)</span></p></blockquote></div><div class="SIntrapara">By assumption the result is <span class="RktVal">#false</span>. The question is how long it
takes to determine this result. While we don&rsquo;t know the precise amount of
time, it is safe to say that checking on the constructor of a list takes a
small and fixed amount of time. Indeed, this assumption also holds for the
next step, when <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._cond%29%29" class="RktStxLink" data-pltdoc="x">cond</a></span> checks what the value of the first condition
is. Since it is <span class="RktVal">#false</span>, the first <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._cond%29%29" class="RktStxLink" data-pltdoc="x">cond</a></span> line is
dropped. Checking whether a <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._cond%29%29" class="RktStxLink" data-pltdoc="x">cond</a></span> line starts with <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._else%29%29" class="RktStxLink" data-pltdoc="x">else</a></span>
is equally fast, which means we are left with
</div><div class="SIntrapara"><blockquote class="SCodeFlow"><p><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._%2B%29%29" class="RktValLink" data-pltdoc="x">+</a></span><span class="hspace">&nbsp;</span><span class="RktPn">(</span><span class="RktSym">how-many</span><span class="hspace">&nbsp;</span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._rest%29%29" class="RktValLink" data-pltdoc="x">rest</a></span><span class="hspace">&nbsp;</span><span class="RktSym">some-non-empty-list</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="hspace">&nbsp;</span><span class="RktVal">1</span><span class="RktPn">)</span></p></blockquote></div><div class="SIntrapara">Finally we may safely assume that <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._rest%29%29" class="RktValLink" data-pltdoc="x">rest</a></span> extracts the remainder of
the list in a fixed amount of time, but otherwise it looks like we are
stuck. To compute how long <span class="RktSym">how-many</span> takes to determine the length
of some list, we need to know how long <span class="RktSym">how-many</span> takes to count
the number of items in the rest of that list.</div></p><p>Alternatively, if we assume that predicates and selectors take some fixed
amount of time, the time it takes <span class="RktSym">how-many</span> to determine the
length of a list depends on the number of recursive steps it
takes. Somewhat more precisely, evaluating <span class="RktPn">(</span><span class="RktSym">how-many</span><span class="stt"> </span><span class="RktSym">some-list</span><span class="RktPn">)</span>
takes roughly <span style="font-style: italic">n</span> times some fixed amount where <span style="font-style: italic">n</span> is the
length of the list or, equivalently, the number of times the program
recurs.</p><p>Generalizing from this example suggests that the running time depends on
the size of the input and that the number of recursive steps is a good
estimate for the length of an evaluation sequence. For this reason,
computer scientists discuss the <span style="font-style: italic">abstract running time</span> of a
program as a relationship between the size of the input and the number of
recursive steps in an evaluation.<span class="refelem"><span class="refcolumn"><span class="refcontent">&ldquo;Abstract&rdquo; because
the measure ignores the details of how much time primitive steps take.</span></span></span>
In our first example, the size of the input is the number of items on the
list. Thus, a list of one item requires one recursive step, a list of two
needs two steps, and for a list of <span style="font-style: italic">n</span> items, it&rsquo;s <span style="font-style: italic">n</span> steps.</p><p>Computer scientists use the phrase a program <span class="RktSym">f</span> takes &ldquo;on the
order of <span style="font-style: italic">n</span> steps&rdquo; to formulate a claim about the abstract running time
of <span class="RktSym">f</span>. To use the phrase correctly, it must come with an
explanation of <span style="font-style: italic">n</span>, for example, &ldquo;it counts the number of items on
the given list&rdquo; or &ldquo;it is the number of digits in the given number.&rdquo;
Without such an explanation, the original phrase is actually meaningless.</p><p><div class="SIntrapara">Not all programs have the kind of simple abstract running time as
<span class="RktSym">how-many</span>. Take a look at the first recursive program in this
book: <a name="(idx._(gentag._696))"></a>
</div><div class="SIntrapara"><blockquote class="SCodeFlow"><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._define%29%29" class="RktStxLink" data-pltdoc="x">define</a></span><span class="hspace">&nbsp;</span><span class="RktPn">(</span><span class="RktSym">contains-flatt?</span><span class="hspace">&nbsp;</span><span class="RktSym">lo-names</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace">&nbsp;&nbsp;</span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._cond%29%29" class="RktStxLink" data-pltdoc="x">cond</a></span></td></tr><tr><td><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="RktPn">[</span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._empty~3f%29%29" class="RktValLink" data-pltdoc="x">empty?</a></span><span class="hspace">&nbsp;</span><span class="RktSym">lo-names</span><span class="RktPn">)</span><span class="hspace">&nbsp;</span><span class="RktVal">#false</span><span class="RktPn">]</span></td></tr><tr><td><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="RktPn">[</span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._cons~3f%29%29" class="RktValLink" data-pltdoc="x">cons?</a></span><span class="hspace">&nbsp;</span><span class="RktSym">lo-names</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._or%29%29" class="RktStxLink" data-pltdoc="x">or</a></span><span class="hspace">&nbsp;</span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._string~3d~3f%29%29" class="RktValLink" data-pltdoc="x">string=?</a></span><span class="hspace">&nbsp;</span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._first%29%29" class="RktValLink" data-pltdoc="x">first</a></span><span class="hspace">&nbsp;</span><span class="RktSym">lo-names</span><span class="RktPn">)</span><span class="hspace">&nbsp;</span><span class="RktVal">'</span><span class="RktVal">flatt</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="RktPn">(</span><span class="RktSym">contains-flatt?</span><span class="hspace">&nbsp;</span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._rest%29%29" class="RktValLink" data-pltdoc="x">rest</a></span><span class="hspace">&nbsp;</span><span class="RktSym">lo-names</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">]</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr></table></blockquote></div><div class="SIntrapara">For a list that starts with <span class="RktVal">'</span><span class="RktVal">flatt</span>, say,
</div><div class="SIntrapara"><blockquote class="SCodeFlow"><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td><span class="RktPn">(</span><span class="RktSym">contains-flatt?</span></td></tr><tr><td><span class="hspace">&nbsp;&nbsp;</span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._list%29%29" class="RktValLink" data-pltdoc="x">list</a></span><span class="hspace">&nbsp;</span><span class="RktVal">"flatt"</span><span class="hspace">&nbsp;</span><span class="RktVal">"robot"</span><span class="hspace">&nbsp;</span><span class="RktVal">"ball"</span><span class="hspace">&nbsp;</span><span class="RktVal">"game-boy"</span><span class="hspace">&nbsp;</span><span class="RktVal">"pokemon"</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr></table></blockquote></div><div class="SIntrapara">the program requires no recursive steps. In contrast, if
<span class="RktVal">'</span><span class="RktVal">flatt</span> occurs at the end of the list, as in,
</div><div class="SIntrapara"><blockquote class="SCodeFlow"><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td><span class="RktPn">(</span><span class="RktSym">contains-flatt?</span></td></tr><tr><td><span class="hspace">&nbsp;&nbsp;</span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._list%29%29" class="RktValLink" data-pltdoc="x">list</a></span><span class="hspace">&nbsp;</span><span class="RktVal">"robot"</span><span class="hspace">&nbsp;</span><span class="RktVal">"ball"</span><span class="hspace">&nbsp;</span><span class="RktVal">"game-boy"</span><span class="hspace">&nbsp;</span><span class="RktVal">"pokemon"</span><span class="hspace">&nbsp;</span><span class="RktVal">"flatt"</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr></table></blockquote></div><div class="SIntrapara">the evaluation needs as many recursive steps as there are items in the
list.</div></p><p><div class="SIntrapara">This second analysis brings us to the second important idea of program
analysis, namely, the kind of analysis that is performed:
</div><div class="SIntrapara"><ul><li><p>A <span style="font-style: italic">best-case analysis</span> focuses on the class of inputs for
which the program can easily find the answer. In our running example, a
list that starts with <span class="RktVal">'</span><span class="RktVal">flatt</span> is the best kind of input.</p></li><li><p>In turn, a <span style="font-style: italic">worst-case analysis</span> determines how badly a
program performs for those inputs that stress it most. The
<span class="RktSym">contains-flatt?</span> function exhibits its worst performance when
<span class="RktVal">'</span><span class="RktVal">flatt</span> is at the end of the input list.</p></li><li><p>Finally, an <span style="font-style: italic">average analysis</span> starts from the ideas that
programmers cannot assume that inputs are always of the best possible
shape and that they must hope that the inputs are not of the worst possible
shape. In many cases, they must estimate the <span style="font-weight: bold">average</span> time a
program takes. For example, <span class="RktSym">contains-flatt?</span> finds, on the
average, <span class="RktVal">'</span><span class="RktVal">flatt</span> somewhere in the middle of the input list. Thus,
if the latter consists of <span style="font-style: italic">n</span> items, the average
running time of <span class="RktSym">contains-flatt?</span> is <img src="pict_238.png" alt="image" width="20" height="12"/>, that is, it
recurs half as often as there are items on the input.</p></li></ul></div><div class="SIntrapara">Computer scientists therefore usually employ the &ldquo;on the order of&rdquo;
phrase in conjunction with &ldquo;on the average&rdquo; or &ldquo;in the worst case.&rdquo;</div></p><p><div class="SIntrapara">Returning to the idea that <span class="RktSym">contains-flatt?</span> uses, on the average,
an &ldquo;order of <img src="pict_239.png" alt="image" width="20" height="12"/> steps&rdquo; brings us to one more characteristic
of abstract running time. Because it ignores the exact time it takes to
evaluate primitive computation steps&#8212;<wbr></wbr>checking predicates, selecting
values, picking <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._cond%29%29" class="RktStxLink" data-pltdoc="x">cond</a></span> clauses&#8212;<wbr></wbr>we can drop the division by
<span style="font-style: italic"></span>2<span style="font-style: italic"></span>. Here is why. By assumption, each basic step takes <span style="font-style: italic">k</span> units
of time, meaning <span class="RktSym">contains-flatt?</span> takes time
</div><div class="SIntrapara"><blockquote class="SCentered"><p><img src="pict_240.png" alt="image" width="45" height="15"/></p></blockquote></div><div class="SIntrapara">If you had a newer computer, these basic computations may run twice as
fast, in which case we would use <img src="pict_241.png" alt="image" width="19" height="12"/> as the constant for basic
work. Let&rsquo;s call this constant <span style="font-style: italic">c</span> and calculate:
</div><div class="SIntrapara"><blockquote class="SCentered"><p><img src="pict_242.png" alt="image" width="135" height="15"/></p></blockquote></div><div class="SIntrapara">that is, the abstract running time is always <span style="font-style: italic">n</span> multiplied by a
constant, and that&rsquo;s all that matters to say &ldquo;on the order of <span style="font-style: italic">n</span>.&rdquo;</div></p><p><div class="SIntrapara">Now consider our sorting program from <a href="part_two.html#%28counter._%28figure._fig~3asort%29%29" data-pltdoc="x">figure&nbsp;<span class="FigureRef">72</span></a>. Here is a
hand-evaluation for a small input, listing all recursive steps:
</div><div class="SIntrapara"><blockquote class="SCodeFlow"><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._sort%29%29" class="RktValLink" data-pltdoc="x">sort</a></span><span class="hspace">&nbsp;</span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._list%29%29" class="RktValLink" data-pltdoc="x">list</a></span><span class="hspace">&nbsp;</span><span class="RktVal">3</span><span class="hspace">&nbsp;</span><span class="RktVal">1</span><span class="hspace">&nbsp;</span><span class="RktVal">2</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr><tr><td><span class="RktSym">==</span><span class="hspace">&nbsp;</span><span class="RktPn">(</span><span class="RktSym">insert</span><span class="hspace">&nbsp;</span><span class="RktVal">3</span><span class="hspace">&nbsp;</span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._sort%29%29" class="RktValLink" data-pltdoc="x">sort</a></span><span class="hspace">&nbsp;</span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._list%29%29" class="RktValLink" data-pltdoc="x">list</a></span><span class="hspace">&nbsp;</span><span class="RktVal">1</span><span class="hspace">&nbsp;</span><span class="RktVal">2</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr><tr><td><span class="RktSym">==</span><span class="hspace">&nbsp;</span><span class="RktPn">(</span><span class="RktSym">insert</span><span class="hspace">&nbsp;</span><span class="RktVal">3</span><span class="hspace">&nbsp;</span><span class="RktPn">(</span><span class="RktSym">insert</span><span class="hspace">&nbsp;</span><span class="RktVal">1</span><span class="hspace">&nbsp;</span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._sort%29%29" class="RktValLink" data-pltdoc="x">sort</a></span><span class="hspace">&nbsp;</span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._list%29%29" class="RktValLink" data-pltdoc="x">list</a></span><span class="hspace">&nbsp;</span><span class="RktVal">2</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr><tr><td><span class="RktSym">==</span><span class="hspace">&nbsp;</span><span class="RktPn">(</span><span class="RktSym">insert</span><span class="hspace">&nbsp;</span><span class="RktVal">3</span><span class="hspace">&nbsp;</span><span class="RktPn">(</span><span class="RktSym">insert</span><span class="hspace">&nbsp;</span><span class="RktVal">1</span><span class="hspace">&nbsp;</span><span class="RktPn">(</span><span class="RktSym">insert</span><span class="hspace">&nbsp;</span><span class="RktVal">2</span><span class="hspace">&nbsp;</span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._sort%29%29" class="RktValLink" data-pltdoc="x">sort</a></span><span class="hspace">&nbsp;</span><span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">)</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr><tr><td><span class="RktSym">==</span><span class="hspace">&nbsp;</span><span class="RktPn">(</span><span class="RktSym">insert</span><span class="hspace">&nbsp;</span><span class="RktVal">3</span><span class="hspace">&nbsp;</span><span class="RktPn">(</span><span class="RktSym">insert</span><span class="hspace">&nbsp;</span><span class="RktVal">1</span><span class="hspace">&nbsp;</span><span class="RktPn">(</span><span class="RktSym">insert</span><span class="hspace">&nbsp;</span><span class="RktVal">2</span><span class="hspace">&nbsp;</span><span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">)</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr><tr><td><span class="RktSym">==</span><span class="hspace">&nbsp;</span><span class="RktPn">(</span><span class="RktSym">insert</span><span class="hspace">&nbsp;</span><span class="RktVal">3</span><span class="hspace">&nbsp;</span><span class="RktPn">(</span><span class="RktSym">insert</span><span class="hspace">&nbsp;</span><span class="RktVal">1</span><span class="hspace">&nbsp;</span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._list%29%29" class="RktValLink" data-pltdoc="x">list</a></span><span class="hspace">&nbsp;</span><span class="RktVal">2</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr><tr><td><span class="RktSym">==</span><span class="hspace">&nbsp;</span><span class="RktPn">(</span><span class="RktSym">insert</span><span class="hspace">&nbsp;</span><span class="RktVal">3</span><span class="hspace">&nbsp;</span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._cons%29%29" class="RktValLink" data-pltdoc="x">cons</a></span><span class="hspace">&nbsp;</span><span class="RktVal">2</span><span class="hspace">&nbsp;</span><span class="RktPn">(</span><span class="RktSym">insert</span><span class="hspace">&nbsp;</span><span class="RktVal">1</span><span class="hspace">&nbsp;</span><span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">)</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr><tr><td><span class="RktSym">==</span><span class="hspace">&nbsp;</span><span class="RktPn">(</span><span class="RktSym">insert</span><span class="hspace">&nbsp;</span><span class="RktVal">3</span><span class="hspace">&nbsp;</span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._list%29%29" class="RktValLink" data-pltdoc="x">list</a></span><span class="hspace">&nbsp;</span><span class="RktVal">2</span><span class="hspace">&nbsp;</span><span class="RktVal">1</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr><tr><td><span class="RktSym">==</span><span class="hspace">&nbsp;</span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._list%29%29" class="RktValLink" data-pltdoc="x">list</a></span><span class="hspace">&nbsp;</span><span class="RktVal">3</span><span class="hspace">&nbsp;</span><span class="RktVal">2</span><span class="hspace">&nbsp;</span><span class="RktVal">1</span><span class="RktPn">)</span></td></tr></table></blockquote></div><div class="SIntrapara">The evaluation shows how <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._sort%29%29" class="RktValLink" data-pltdoc="x">sort</a></span> traverses the given list and how it
sets up an application of <span class="RktSym">insert</span> for each number in the list. Put
differently, <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._sort%29%29" class="RktValLink" data-pltdoc="x">sort</a></span> is a two-phase program. During the first one,
the recursive steps for <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._sort%29%29" class="RktValLink" data-pltdoc="x">sort</a></span> set up as many applications of
<span class="RktSym">insert</span> as there are items in the list. During the second phase,
each application of <span class="RktSym">insert</span> traverses a sorted list.</div></p><p>Inserting an item is similar to finding one, so it is not surprising
that the performance of <span class="RktSym">insert</span> and <span class="RktSym">contains-flatt?</span> are
alike. The applications of <span class="RktSym">insert</span> to a list of <span style="font-style: italic">l</span> items
triggers between <span style="font-style: italic"></span>0<span style="font-style: italic"></span> and <span style="font-style: italic">l</span> recursive steps. On the average, we
assume it requires <span style="font-style: italic">l/</span>2<span style="font-style: italic"></span>, which means
that <span class="RktSym">insert</span> takes &ldquo;on the order of <span style="font-style: italic">l</span> steps&rdquo; where
<span style="font-style: italic">l</span> is the length of the given list.</p><p><div class="SIntrapara">The question is how long these lists are to which <span class="RktSym">insert</span> adds
numbers. Generalizing from the above calculation, we can see that the
first one is <img src="pict_243.png" alt="image" width="29" height="9"/> items long, the second one <img src="pict_244.png" alt="image" width="29" height="9"/>, and so
on, all the way down to the empty list. Hence, we get that <span class="RktSym">insert</span>
performs
</div><div class="SIntrapara"><blockquote class="SCentered"><p><img src="pict_245.png" alt="image" width="365" height="17"/></p></blockquote></div><div class="SIntrapara">meaning
</div><div class="SIntrapara"><blockquote class="SCentered"><p><img src="pict_246.png" alt="image" width="68" height="15"/></p></blockquote></div><div class="SIntrapara">represents the best &ldquo;guess&rdquo; at the average number of insertion steps.
In this last term, <span style="font-style: italic">n</span><span style="vertical-align: super; font-size: 80%"><span style="font-style: italic"></span>2<span style="font-style: italic"></span></span><span style="font-style: italic"></span> is the dominant factor, and so we say that a
sorting process takes &ldquo;on the order of <span style="font-style: italic">n</span><span style="vertical-align: super; font-size: 80%"><span style="font-style: italic"></span>2<span style="font-style: italic"></span></span><span style="font-style: italic"></span> steps.&rdquo;
<a href="i5-6.html#%28counter._%28exercise._ex~3abig-o1%29%29" data-pltdoc="x">Exercise&nbsp;486</a> ask you to argue why it is correct to simplify this
claim in this way.</div></p><p>See <a href="i5-6.html#%28counter._%28exercise._ex~3abig-o1%29%29" data-pltdoc="x">exercise&nbsp;486</a> for why this is the case.</p><p>We can also proceed with less formalism and rigor. Because <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._sort%29%29" class="RktValLink" data-pltdoc="x">sort</a></span>
uses <span class="RktSym">insert</span> once per item on the list, we get an &ldquo;order of
<span style="font-style: italic">n</span>&rdquo; <span class="RktSym">insert</span> steps where <span style="font-style: italic">n</span> is the size of the
list. Since <span class="RktSym">insert</span> needs <img src="pict_247.png" alt="image" width="20" height="12"/> steps, we now see that a
sorting process needs <img src="pict_248.png" alt="image" width="36" height="12"/> steps or &ldquo;on the order of
<span style="font-style: italic">n</span><span style="vertical-align: super; font-size: 80%"><span style="font-style: italic"></span>2<span style="font-style: italic"></span></span><span style="font-style: italic"></span>.&rdquo;</p><p><div class="SIntrapara">Totaling it all up, we get that <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._sort%29%29" class="RktValLink" data-pltdoc="x">sort</a></span> takes on the &ldquo;order of
<span style="font-style: italic">n</span> steps&rdquo; plus <span style="font-style: italic">n</span><span style="vertical-align: super; font-size: 80%"><span style="font-style: italic"></span>2<span style="font-style: italic"></span></span><span style="font-style: italic"></span> recursive steps in <span class="RktSym">insert</span> for a
list of <span style="font-style: italic">n</span> items, which yields
</div><div class="SIntrapara"><blockquote class="SCentered"><p><img src="pict_249.png" alt="image" width="35" height="11"/></p></blockquote></div><div class="SIntrapara">steps. See again <a href="i5-6.html#%28counter._%28exercise._ex~3abig-o1%29%29" data-pltdoc="x">exercise&nbsp;486</a> for details.
<span style="font-weight: bold">Note</span> This analysis assumes that comparing two items on the list
takes a fixed amount of time. <span style="font-weight: bold">End</span></div></p><p><div class="SIntrapara">Our final example is the <span class="RktSym">inf</span> program from <a href="part_three.html#%28part._sec~3alocal-definitions%29" data-pltdoc="x">Local Definitions</a>:<a name="(idx._(gentag._697))"></a>
</div><div class="SIntrapara"><blockquote class="SCodeFlow"><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._define%29%29" class="RktStxLink" data-pltdoc="x">define</a></span><span class="hspace">&nbsp;</span><span class="RktPn">(</span><span class="RktSym">inf</span><span class="hspace">&nbsp;</span><span class="RktSym">l</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace">&nbsp;&nbsp;</span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._cond%29%29" class="RktStxLink" data-pltdoc="x">cond</a></span></td></tr><tr><td><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="RktPn">[</span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._empty~3f%29%29" class="RktValLink" data-pltdoc="x">empty?</a></span><span class="hspace">&nbsp;</span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._rest%29%29" class="RktValLink" data-pltdoc="x">rest</a></span><span class="hspace">&nbsp;</span><span class="RktSym">l</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="hspace">&nbsp;</span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._first%29%29" class="RktValLink" data-pltdoc="x">first</a></span><span class="hspace">&nbsp;</span><span class="RktSym">l</span><span class="RktPn">)</span><span class="RktPn">]</span></td></tr><tr><td><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="RktPn">[</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._else%29%29" class="RktStxLink" data-pltdoc="x">else</a></span><span class="hspace">&nbsp;</span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._if%29%29" class="RktStxLink" data-pltdoc="x">if</a></span><span class="hspace">&nbsp;</span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._~3c%29%29" class="RktValLink" data-pltdoc="x">&lt;</a></span><span class="hspace">&nbsp;</span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._first%29%29" class="RktValLink" data-pltdoc="x">first</a></span><span class="hspace">&nbsp;</span><span class="RktSym">l</span><span class="RktPn">)</span><span class="hspace">&nbsp;</span><span class="RktPn">(</span><span class="RktSym">inf</span><span class="hspace">&nbsp;</span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._rest%29%29" class="RktValLink" data-pltdoc="x">rest</a></span><span class="hspace">&nbsp;</span><span class="RktSym">l</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._first%29%29" class="RktValLink" data-pltdoc="x">first</a></span><span class="hspace">&nbsp;</span><span class="RktSym">l</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="RktPn">(</span><span class="RktSym">inf</span><span class="hspace">&nbsp;</span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._rest%29%29" class="RktValLink" data-pltdoc="x">rest</a></span><span class="hspace">&nbsp;</span><span class="RktSym">l</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">]</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr></table></blockquote></div></p><p><div class="SIntrapara">Let&rsquo;s start with a small input: <span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._list%29%29" class="RktValLink" data-pltdoc="x">list</a></span><span class="stt"> </span><span class="RktVal">3</span><span class="stt"> </span><span class="RktVal">2</span><span class="stt"> </span><span class="RktVal">1</span><span class="stt"> </span><span class="RktVal">0</span><span class="RktPn">)</span>. We know that the
result is <span class="RktVal">0</span>. Here is the first important step of a hand-evaluation:
</div><div class="SIntrapara"><blockquote class="SCodeFlow"><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td><span class="RktPn">(</span><span class="RktSym">inf</span><span class="hspace">&nbsp;</span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._list%29%29" class="RktValLink" data-pltdoc="x">list</a></span><span class="hspace">&nbsp;</span><span class="RktVal">3</span><span class="hspace">&nbsp;</span><span class="RktVal">2</span><span class="hspace">&nbsp;</span><span class="RktVal">1</span><span class="hspace">&nbsp;</span><span class="RktVal">0</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr><tr><td><span class="RktSym">==</span></td></tr><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._if%29%29" class="RktStxLink" data-pltdoc="x">if</a></span><span class="hspace">&nbsp;</span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._~3c%29%29" class="RktValLink" data-pltdoc="x">&lt;</a></span><span class="hspace">&nbsp;</span><span class="RktVal">3</span><span class="hspace">&nbsp;</span><span class="highlighted"><span class="RktPn">(</span><span class="RktSym">inf</span><span class="stt"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._list%29%29" class="RktValLink" data-pltdoc="x">list</a></span><span class="stt"> </span><span class="RktVal">2</span><span class="stt"> </span><span class="RktVal">1</span><span class="stt"> </span><span class="RktVal">0</span><span class="RktPn">)</span><span class="RktPn">)</span></span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="RktVal">3</span></td></tr><tr><td><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="highlighted"><span class="RktPn">(</span><span class="RktSym">inf</span><span class="stt"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._list%29%29" class="RktValLink" data-pltdoc="x">list</a></span><span class="stt"> </span><span class="RktVal">2</span><span class="stt"> </span><span class="RktVal">1</span><span class="stt"> </span><span class="RktVal">0</span><span class="RktPn">)</span><span class="RktPn">)</span></span><span class="RktPn">)</span></td></tr></table></blockquote></div><div class="SIntrapara">From here, we must evaluate the first recursive call. Because the result is
<span class="RktVal">0</span> and the condition is thus <span class="RktVal">#false</span>, we must evaluate the
recursion in the else-branch as well.</div></p><p><div class="SIntrapara">Once we do so, we see two evaluations of <span class="RktPn">(</span><span class="RktSym">inf</span><span class="stt"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._list%29%29" class="RktValLink" data-pltdoc="x">list</a></span><span class="stt"> </span><span class="RktVal">1</span><span class="stt"> </span><span class="RktVal">0</span><span class="RktPn">)</span><span class="RktPn">)</span>:
</div><div class="SIntrapara"><blockquote class="SCodeFlow"><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td><span class="RktPn">(</span><span class="RktSym">inf</span><span class="hspace">&nbsp;</span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._list%29%29" class="RktValLink" data-pltdoc="x">list</a></span><span class="hspace">&nbsp;</span><span class="RktVal">2</span><span class="hspace">&nbsp;</span><span class="RktVal">1</span><span class="hspace">&nbsp;</span><span class="RktVal">0</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr><tr><td><span class="RktSym">==</span></td></tr><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._if%29%29" class="RktStxLink" data-pltdoc="x">if</a></span><span class="hspace">&nbsp;</span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._~3c%29%29" class="RktValLink" data-pltdoc="x">&lt;</a></span><span class="hspace">&nbsp;</span><span class="RktVal">2</span><span class="hspace">&nbsp;</span><span class="RktPn">(</span><span class="RktSym">inf</span><span class="hspace">&nbsp;</span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._list%29%29" class="RktValLink" data-pltdoc="x">list</a></span><span class="hspace">&nbsp;</span><span class="RktVal">1</span><span class="hspace">&nbsp;</span><span class="RktVal">0</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="hspace">&nbsp;</span><span class="RktVal">2</span><span class="hspace">&nbsp;</span><span class="RktPn">(</span><span class="RktSym">inf</span><span class="hspace">&nbsp;</span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._list%29%29" class="RktValLink" data-pltdoc="x">list</a></span><span class="hspace">&nbsp;</span><span class="RktVal">1</span><span class="hspace">&nbsp;</span><span class="RktVal">0</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr></table></blockquote></div><div class="SIntrapara">At this point we can generalize the pattern and summarize it in a table:
</div><div class="SIntrapara"><blockquote><table cellspacing="0" cellpadding="0" style="border-collapse: collapse;"><tr><td style="border-bottom: 1px solid black;"><p>original expression</p></td><td style="border-bottom: 1px solid black;"><p><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span></p></td><td style="border-bottom: 1px solid black;"><p>requires two evaluations of</p></td></tr><tr><td><p><span class="RktPn">(</span><span class="RktSym">inf</span><span class="stt"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._list%29%29" class="RktValLink" data-pltdoc="x">list</a></span><span class="stt"> </span><span class="RktVal">3</span><span class="stt"> </span><span class="RktVal">2</span><span class="stt"> </span><span class="RktVal">1</span><span class="stt"> </span><span class="RktVal">0</span><span class="RktPn">)</span><span class="RktPn">)</span></p></td><td><p><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span></p></td><td><p><span class="RktPn">(</span><span class="RktSym">inf</span><span class="stt"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._list%29%29" class="RktValLink" data-pltdoc="x">list</a></span><span class="stt"> </span><span class="RktVal">2</span><span class="stt"> </span><span class="RktVal">1</span><span class="stt"> </span><span class="RktVal">0</span><span class="RktPn">)</span><span class="RktPn">)</span></p></td></tr><tr><td><p><span class="RktPn">(</span><span class="RktSym">inf</span><span class="stt"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._list%29%29" class="RktValLink" data-pltdoc="x">list</a></span><span class="stt"> </span><span class="RktVal">2</span><span class="stt"> </span><span class="RktVal">1</span><span class="stt"> </span><span class="RktVal">0</span><span class="RktPn">)</span><span class="RktPn">)</span></p></td><td><p><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span></p></td><td><p><span class="RktPn">(</span><span class="RktSym">inf</span><span class="stt"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._list%29%29" class="RktValLink" data-pltdoc="x">list</a></span><span class="stt"> </span><span class="RktVal">1</span><span class="stt"> </span><span class="RktVal">0</span><span class="RktPn">)</span><span class="RktPn">)</span></p></td></tr><tr><td><p><span class="RktPn">(</span><span class="RktSym">inf</span><span class="stt"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._list%29%29" class="RktValLink" data-pltdoc="x">list</a></span><span class="stt"> </span><span class="RktVal">1</span><span class="stt"> </span><span class="RktVal">0</span><span class="RktPn">)</span><span class="RktPn">)</span></p></td><td><p><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span></p></td><td><p><span class="RktPn">(</span><span class="RktSym">inf</span><span class="stt"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._list%29%29" class="RktValLink" data-pltdoc="x">list</a></span><span class="stt"> </span><span class="RktVal">0</span><span class="RktPn">)</span><span class="RktPn">)</span></p></td></tr></table></blockquote></div><div class="SIntrapara">In total, the hand-evaluation requires eight recursive steps for a list of
four items. If we added <span class="RktVal">4</span> to the front of the list, we would double the
number of recursive steps again. Speaking algebraically, <span class="RktSym">inf</span> needs
on the order of <span style="font-style: italic"></span>2<span style="font-style: italic"></span><span style="vertical-align: super; font-size: 80%"><span style="font-style: italic">n</span></span><span style="font-style: italic"></span> recursive steps for a list of <span style="font-style: italic">n</span> numbers
when the last number is the maximum, which is clearly the worst case for
<span class="RktSym">inf</span>.</div></p><p>Stop! If you paid close attention, you know that the above suggestion is
sloppy. The <span class="RktSym">inf</span> program really just needs <img src="pict_250.png" alt="image" width="25" height="10"/>
recursive steps for a list of <span style="font-style: italic">n</span> items. What is going on?</p><p><div class="SIntrapara">Remember that we don&rsquo;t really measure the exact time when we say &ldquo;on the
order of.&rdquo; Instead we skip over all built-in predicates,
selectors, constructors, arithmetic, and so on and focus on recursive
steps only. Now consider this calculation:
</div><div class="SIntrapara"><blockquote class="SCentered"><p><img src="pict_251.png" alt="image" width="77" height="15"/></p></blockquote></div><div class="SIntrapara">It shows that <img src="pict_252.png" alt="image" width="25" height="10"/> and <img src="pict_253.png" alt="image" width="12" height="8"/> differ by a small factor:
<span style="font-style: italic"></span>2<span style="font-style: italic"></span>, meaning &ldquo;on the order of <img src="pict_254.png" alt="image" width="25" height="10"/> steps&rdquo; describes
<span class="RktSym">inf</span> in a world where all basic operations provided by <span class="stt">*SL</span> run
at half the speed when compared to an <span class="RktSym">inf</span> program that runs at
&ldquo;the order of <img src="pict_255.png" alt="image" width="12" height="8"/> steps.&rdquo; In this sense, the two expressions
really mean the same thing. The question is what exactly they mean, and
that is the subject of the next section.</div></p><p><div class="SIntrapara"><a name="(counter._(exercise._ex~3aorder-of-0))"></a><span style="font-weight: bold">Exercise</span>&nbsp;484. While a list sorted in descending order is
clearly the worst possible input for <span class="RktSym">inf</span>, the analysis of
<span class="RktSym">inf</span>&rsquo;s abstract running time explains why the rewrite of
<span class="RktSym">inf</span> with <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._local%29%29" class="RktStxLink" data-pltdoc="x">local</a></span> reduces the running time. For
convenience, we replicate this version here: <a name="(idx._(gentag._698))"></a>
</div><div class="SIntrapara"><blockquote class="SCodeFlow"><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._define%29%29" class="RktStxLink" data-pltdoc="x">define</a></span><span class="hspace">&nbsp;</span><span class="RktPn">(</span><span class="RktSym">infL</span><span class="hspace">&nbsp;</span><span class="RktSym">l</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace">&nbsp;&nbsp;</span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._cond%29%29" class="RktStxLink" data-pltdoc="x">cond</a></span></td></tr><tr><td><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="RktPn">[</span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._empty~3f%29%29" class="RktValLink" data-pltdoc="x">empty?</a></span><span class="hspace">&nbsp;</span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._rest%29%29" class="RktValLink" data-pltdoc="x">rest</a></span><span class="hspace">&nbsp;</span><span class="RktSym">l</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="hspace">&nbsp;</span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._first%29%29" class="RktValLink" data-pltdoc="x">first</a></span><span class="hspace">&nbsp;</span><span class="RktSym">l</span><span class="RktPn">)</span><span class="RktPn">]</span></td></tr><tr><td><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="RktPn">[</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._else%29%29" class="RktStxLink" data-pltdoc="x">else</a></span><span class="hspace">&nbsp;</span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._local%29%29" class="RktStxLink" data-pltdoc="x">local</a></span><span class="hspace">&nbsp;</span><span class="RktPn">(</span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._define%29%29" class="RktStxLink" data-pltdoc="x">define</a></span><span class="hspace">&nbsp;</span><span class="RktSym">s</span><span class="hspace">&nbsp;</span><span class="RktPn">(</span><span class="RktSym">infL</span><span class="hspace">&nbsp;</span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._rest%29%29" class="RktValLink" data-pltdoc="x">rest</a></span><span class="hspace">&nbsp;</span><span class="RktSym">l</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._if%29%29" class="RktStxLink" data-pltdoc="x">if</a></span><span class="hspace">&nbsp;</span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._~3c%29%29" class="RktValLink" data-pltdoc="x">&lt;</a></span><span class="hspace">&nbsp;</span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._first%29%29" class="RktValLink" data-pltdoc="x">first</a></span><span class="hspace">&nbsp;</span><span class="RktSym">l</span><span class="RktPn">)</span><span class="hspace">&nbsp;</span><span class="RktSym">s</span><span class="RktPn">)</span><span class="hspace">&nbsp;</span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._first%29%29" class="RktValLink" data-pltdoc="x">first</a></span><span class="hspace">&nbsp;</span><span class="RktSym">l</span><span class="RktPn">)</span><span class="hspace">&nbsp;</span><span class="RktSym">s</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">]</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr></table></blockquote></div><div class="SIntrapara">Hand-evaluate <span class="RktPn">(</span><span class="RktSym">infL</span><span class="stt"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._list%29%29" class="RktValLink" data-pltdoc="x">list</a></span><span class="stt"> </span><span class="RktVal">3</span><span class="stt"> </span><span class="RktVal">2</span><span class="stt"> </span><span class="RktVal">1</span><span class="stt"> </span><span class="RktVal">0</span><span class="RktPn">)</span><span class="RktPn">)</span>. Then argue that
<span class="RktSym">infL</span> uses on the &ldquo;order of <span style="font-style: italic">n</span> steps&rdquo; in
the best and the worst case. You may now wish to revisit
<a href="part_three.html#%28counter._%28exercise._ex~3alocal-interm1%29%29" data-pltdoc="x">exercise&nbsp;261</a>, which asks you to explore a similar problem. <a href="i5-6.html#%28counter._%28exercise._ex~3aorder-of-0%29%29" class="ex-end" data-pltdoc="x"></a></div></p><p><a name="(counter._(exercise._ex~3aorder-of-2))"></a><span style="font-weight: bold">Exercise</span>&nbsp;485. A number tree is either a number or a pair of
number trees. Design <span class="RktSym">sum-tree</span>, which determines the
sum of the numbers in a tree. What is its abstract running time? What is
an acceptable measure of the size of such a tree? What is the worst
possible shape of the tree? What&rsquo;s the best possible shape? <a href="i5-6.html#%28counter._%28exercise._ex~3aorder-of-2%29%29" class="ex-end" data-pltdoc="x"></a></p><h3><a name="(part._.The_.Definition_of__.On_the_.Order_.Of_)"></a>The Definition of &ldquo;On the Order Of&rdquo;</h3><p><div class="SIntrapara">The preceding section alluded to all the key ingredients of the phrase &ldquo;on
the order of.&rdquo; Now it is time to introduce a rigorous description of the
phrase. Let&rsquo;s start with the two ideas that the preceding section
develops:
</div><div class="SIntrapara"><ol><li><p>The abstract measurement of performance is a relationship between
two quantities: the size of the input and the number of recursive steps
needed to determine the answer. The relationship is actually a
mathematical function that maps one natural number (the size of the
input) to another (the time needed).</p></li><li><p>Hence, a general statement about the performance of a program is a
statement about a function, and a comparison of the performance of two
programs calls for the comparison of two such functions.</p></li></ol></div><div class="SIntrapara">How do you decide whether one such function is &ldquo;better&rdquo; than another?</div></p><blockquote class="refpara"><blockquote class="refcolumn"><blockquote class="refcontent"><p><a href="part_three.html#%28counter._%28exercise._ex~3asem2-funcs%29%29" data-pltdoc="x">Exercise&nbsp;245</a> tackles a different question, namely,
whether we can formulate a program that decides whether two other programs
are equal. In this intermezzo, we are not writing a program;
we are using plain mathematical arguments.</p></blockquote></blockquote></blockquote><p><div class="SIntrapara">Let&rsquo;s return to the imaginary programs from the introduction: <span class="RktSym">prog-linear</span><span class="RktMeta"></span> and
<span class="RktSym">prog-square</span><span class="RktMeta"></span>. They compute the same results but their performance differs. The
<span class="RktSym">prog-linear</span><span class="RktMeta"></span> program requires &ldquo;on the order of <span style="font-style: italic">n</span> steps&rdquo; while <span class="RktSym">prog-square</span><span class="RktMeta"></span>
uses &ldquo;on the order of <span style="font-style: italic">n</span><span style="vertical-align: super; font-size: 80%"><span style="font-style: italic"></span>2<span style="font-style: italic"></span></span><span style="font-style: italic"></span> steps.&rdquo; Mathematically speaking, the
performance function for <span class="RktSym">prog-linear</span><span class="RktMeta"></span> is
</div><div class="SIntrapara"><blockquote class="SCentered"><p><img src="pict_256.png" alt="image" width="71" height="12"/></p></blockquote></div><div class="SIntrapara">and <span class="RktSym">prog-square</span><span class="RktMeta"></span>&rsquo;s associated performance function is
</div><div class="SIntrapara"><blockquote class="SCentered"><p><img src="pict_257.png" alt="image" width="76" height="13"/></p></blockquote></div><div class="SIntrapara">In these definitions, <span style="font-style: italic">c</span><span style="vertical-align: sub; font-size: 80%"><span style="font-style: italic">L</span></span><span style="font-style: italic"></span> is the cost for each recursive step in
<span class="RktSym">prog-square</span><span class="RktMeta"></span> and <span style="font-style: italic">c</span><span style="vertical-align: sub; font-size: 80%"><span style="font-style: italic">S</span></span><span style="font-style: italic"></span> is the cost per step in <span class="RktSym">prog-linear</span><span class="RktMeta"></span>.</div></p><p>Say we figure out that <span style="font-style: italic">c</span><span style="vertical-align: sub; font-size: 80%"><span style="font-style: italic">L</span></span><span style="font-style: italic"> = </span>1<span style="font-style: italic"></span>0<span style="font-style: italic"></span>0<span style="font-style: italic"></span>0<span style="font-style: italic"></span> and <span style="font-style: italic">c</span><span style="vertical-align: sub; font-size: 80%"><span style="font-style: italic">S</span></span><span style="font-style: italic"> = </span>1<span style="font-style: italic"></span>. Then we can
tabulate these abstract running times to make the comparison concrete:</p><p><div class="SIntrapara"><blockquote><table cellspacing="0" cellpadding="0" style="border-collapse: collapse;"><tr><td align="right" style="border-bottom: 1px solid black;"><p><span style="font-style: italic">n</span></p></td><td align="right" style="border-bottom: 1px solid black;"><p><span class="hspace">&nbsp;&nbsp;&nbsp;</span></p></td><td align="right" style="border-bottom: 1px solid black;"><p>10</p></td><td align="right" style="border-bottom: 1px solid black;"><p><span class="hspace">&nbsp;&nbsp;&nbsp;</span></p></td><td align="right" style="border-bottom: 1px solid black;"><p>100</p></td><td align="right" style="border-bottom: 1px solid black;"><p><span class="hspace">&nbsp;&nbsp;&nbsp;</span></p></td><td align="right" style="border-bottom: 1px solid black;"><p>1000</p></td><td align="right" style="border-bottom: 1px solid black;"><p><span class="hspace">&nbsp;&nbsp;&nbsp;</span></p></td><td align="right" style="border-bottom: 1px solid black;"><p>2000</p></td></tr><tr><td align="right"><p><span class="RktSym">prog-square</span><span class="RktMeta"></span></p></td><td align="right"><p><span class="hspace">&nbsp;&nbsp;&nbsp;</span></p></td><td align="right"><p>100</p></td><td align="right"><p><span class="hspace">&nbsp;&nbsp;&nbsp;</span></p></td><td align="right"><p>10000</p></td><td align="right"><p><span class="hspace">&nbsp;&nbsp;&nbsp;</span></p></td><td align="right"><p>1000000</p></td><td align="right"><p><span class="hspace">&nbsp;&nbsp;&nbsp;</span></p></td><td align="right"><p>4000000</p></td></tr><tr><td align="right"><p><span class="RktSym">prog-linear</span><span class="RktMeta"></span></p></td><td align="right"><p><span class="hspace">&nbsp;&nbsp;&nbsp;</span></p></td><td align="right"><p>10000</p></td><td align="right"><p><span class="hspace">&nbsp;&nbsp;&nbsp;</span></p></td><td align="right"><p>100000</p></td><td align="right"><p><span class="hspace">&nbsp;&nbsp;&nbsp;</span></p></td><td align="right"><p>1000000</p></td><td align="right"><p><span class="hspace">&nbsp;&nbsp;&nbsp;</span></p></td><td align="right"><p>2000000</p></td></tr></table></blockquote></div><div class="SIntrapara">Like the graphs in <a href="i5-6.html#%28counter._%28figure._fig~3aperformance%29%29" data-pltdoc="x">figure&nbsp;<span class="FigureRef">176</span></a>, the table at first seems
to say that <span class="RktSym">prog-square</span><span class="RktMeta"></span> is better than <span class="RktSym">prog-linear</span><span class="RktMeta"></span>, because for inputs of the same
size <span style="font-style: italic">n</span>, <span class="RktSym">prog-square</span><span class="RktMeta"></span>&rsquo;s result is smaller than <span class="RktSym">prog-linear</span><span class="RktMeta"></span>&rsquo;s. But look at the
last column in the table. Once the inputs are sufficiently large,
<span class="RktSym">prog-square</span><span class="RktMeta"></span>&rsquo;s advantage decreases until it disappears at an input size of
<span style="font-style: italic"></span>1<span style="font-style: italic"></span>0<span style="font-style: italic"></span>0<span style="font-style: italic"></span>0<span style="font-style: italic"></span>. <span style="font-weight: bold">Thereafter</span> <span class="RktSym">prog-square</span><span class="RktMeta"></span> is <span style="font-weight: bold">always</span> slower than
<span class="RktSym">prog-linear</span><span class="RktMeta"></span>.</div></p><p>This last insight is the key to the precise definition of the phrase
&ldquo;order of.&rdquo; If a function <span style="font-style: italic">f</span> on the natural numbers produces
larger numbers than some function <span style="font-style: italic">g</span> <span style="font-weight: bold">for all</span> natural numbers,
then <span style="font-style: italic">f</span> is clearly larger than <span style="font-style: italic">g</span>. But what if this comparison
fails for just a few inputs, say for <span style="font-style: italic"></span>1<span style="font-style: italic"></span>0<span style="font-style: italic"></span>0<span style="font-style: italic"></span>0<span style="font-style: italic"></span> or <span style="font-style: italic"></span>1<span style="font-style: italic"></span>0<span style="font-style: italic"></span>0<span style="font-style: italic"></span>0<span style="font-style: italic"></span>0<span style="font-style: italic"></span>0<span style="font-style: italic"></span>0<span style="font-style: italic"></span>, and
holds for all others? In that case, we would still like to say <span style="font-style: italic">f</span>
is better than <span style="font-style: italic">g</span>. And this brings us to the following definition.</p><blockquote><p><div class="SIntrapara"><span style="font-weight: bold">Definition</span> Given a function <span style="font-style: italic">g</span> on the natural numbers,
<span style="font-style: italic">O</span>(<span style="font-style: italic">g</span>)<span style="font-style: italic"></span> (pronounced: &ldquo;big-O of g&rdquo;) is a class of functions on
natural numbers. A function <span style="font-style: italic">f</span> is a member of <span style="font-style: italic">O</span>(<span style="font-style: italic">g</span>)<span style="font-style: italic"></span> if
<span style="font-weight: bold">there exist</span> numbers <span style="font-style: italic">c</span> and <span style="font-style: italic">bigEnough</span> such that
</div><div class="SIntrapara"><blockquote class="SCentered"><p><span style="font-weight: bold">for all</span>
<img src="pict_258.png" alt="image" width="79" height="12"/>
it is true that
<img src="pict_259.png" alt="image" width="84" height="12"/></p></blockquote></div></p><p><span style="font-weight: bold">Terminology</span> If <img src="pict_260.png" alt="image" width="48" height="12"/>, we say <span style="font-style: italic">f</span> is no worse than
<span style="font-style: italic">g</span>.</p></blockquote><p><div class="SIntrapara">Naturally, we would love to illustrate this definition with the example of
<span class="RktSym">prog-linear</span><span class="RktMeta"></span> and <span class="RktSym">prog-square</span><span class="RktMeta"></span> from above. Recall the performance functions for <span class="RktSym">prog-linear</span><span class="RktMeta"></span>
and <span class="RktSym">prog-square</span><span class="RktMeta"></span>, with the constants plugged in:
</div><div class="SIntrapara"><blockquote class="SCentered"><p><img src="pict_261.png" alt="image" width="70" height="13"/></p></blockquote></div><div class="SIntrapara">and
</div><div class="SIntrapara"><blockquote class="SCentered"><p><img src="pict_262.png" alt="image" width="89" height="12"/></p></blockquote></div><div class="SIntrapara">The key is to find the magic numbers <span style="font-style: italic">c</span> and
<span style="font-style: italic">bigEnough</span> such that <img src="pict_263.png" alt="image" width="51" height="12"/>, which would validate that
<span class="RktSym">prog-square</span><span class="RktMeta"></span>&rsquo;s performance is no worse than <span class="RktSym">prog-linear</span><span class="RktMeta"></span>&rsquo;s. For now, we just
tell you what these numbers are:
</div><div class="SIntrapara"><blockquote class="SCentered"><p><img src="pict_264.png" alt="image" width="135" height="12"/></p></blockquote></div><div class="SIntrapara">Using these numbers, we need to show that
</div><div class="SIntrapara"><blockquote class="SCentered"><p><img src="pict_265.png" alt="image" width="82" height="12"/></p></blockquote></div><div class="SIntrapara">for every single <span style="font-style: italic">n</span> larger than <span style="font-style: italic"></span>1<span style="font-style: italic"></span>0<span style="font-style: italic"></span>0<span style="font-style: italic"></span>0<span style="font-style: italic"></span>. Here is how this kind
of argument is spelled out:
</div><div class="SIntrapara"><blockquote><p><div class="SIntrapara">Pick some specific <span style="font-style: italic">n</span><span style="vertical-align: sub; font-size: 80%"><span style="font-style: italic"></span>0<span style="font-style: italic"></span></span><span style="font-style: italic"></span> that satisfies the
condition:
</div><div class="SIntrapara"><blockquote><p><img src="pict_266.png" alt="image" width="59" height="10"/></p></blockquote></div><div class="SIntrapara">We use the symbolic name <span style="font-style: italic">n</span><span style="vertical-align: sub; font-size: 80%"><span style="font-style: italic"></span>0<span style="font-style: italic"></span></span><span style="font-style: italic"></span> so that we don&rsquo;t make any specific
assumptions about it. Now recall from algebra that you can multiply both
sides of the inequality with the same positive factor, and the inequality
still holds. We use <span style="font-style: italic">n</span><span style="vertical-align: sub; font-size: 80%"><span style="font-style: italic"></span>0<span style="font-style: italic"></span></span><span style="font-style: italic"></span>:
</div><div class="SIntrapara"><blockquote><p><img src="pict_267.png" alt="image" width="103" height="10"/></p></blockquote></div><div class="SIntrapara">At this point, it is time to observe that the left side of the inequality
is just <span style="font-style: italic">L</span>(<span style="font-style: italic">n</span><span style="vertical-align: sub; font-size: 80%"><span style="font-style: italic"></span>0<span style="font-style: italic"></span></span><span style="font-style: italic"></span>)<span style="font-style: italic"></span> and the right side is <span style="font-style: italic">S</span>(<span style="font-style: italic">n</span><span style="vertical-align: sub; font-size: 80%"><span style="font-style: italic"></span>0<span style="font-style: italic"></span></span><span style="font-style: italic"></span>)<span style="font-style: italic"></span>:
</div><div class="SIntrapara"><blockquote><p><img src="pict_268.png" alt="image" width="84" height="12"/></p></blockquote></div><div class="SIntrapara">Since <span style="font-style: italic">n</span><span style="vertical-align: sub; font-size: 80%"><span style="font-style: italic"></span>0<span style="font-style: italic"></span></span><span style="font-style: italic"></span> is a generic number of the right kind, we have shown
exactly what we wanted to show.</div></p></blockquote></div><div class="SIntrapara">Usually you find <span style="font-style: italic">bigEnough</span> and <span style="font-style: italic">c</span> by working your way backward
through such an argument. While this kind of mathematical reasoning is
fascinating, we leave it to a course on algorithms.</div></p><p><div class="SIntrapara">The definition of <span style="font-style: italic">O</span> also explains with mathematical rigor why we don&rsquo;t
have to pay attention to specific constants in our comparisons of abstract
running times. Say we can make each basic step of <span class="RktSym">prog-linear</span><span class="RktMeta"></span> go twice as
fast so that we have:
</div><div class="SIntrapara"><blockquote class="SCentered"><p><img src="pict_269.png" alt="image" width="72" height="15"/></p></blockquote></div><div class="SIntrapara">and
</div><div class="SIntrapara"><blockquote class="SCentered"><p><img src="pict_270.png" alt="image" width="89" height="12"/></p></blockquote></div><div class="SIntrapara">The above argument goes through by doubling <span style="font-style: italic">bigEnough</span> to <span style="font-style: italic"></span>2<span style="font-style: italic"></span>0<span style="font-style: italic"></span>0<span style="font-style: italic"></span>0<span style="font-style: italic"></span>.</div></p><p>Finally, most people use <span style="font-style: italic">O</span> together with a short-hand for stating
functions. Thus they say <span class="RktSym">how-many</span>&rsquo;s running time is
<span style="font-style: italic">O</span>(<span style="font-style: italic">n</span>)<span style="font-style: italic"></span>&#8212;<wbr></wbr>because they tend to think of <span style="font-style: italic">n</span> as an abbreviation of
the (mathematical) function <span style="font-style: italic">id</span>(<span style="font-style: italic">n</span>)<span style="font-style: italic"> = n</span>. Similarly, this use yields
the claim that <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._sort%29%29" class="RktValLink" data-pltdoc="x">sort</a></span>&rsquo;s worst-case running time is <span style="font-style: italic">O</span>(<span style="font-style: italic">n</span><span style="vertical-align: super; font-size: 80%"><span style="font-style: italic"></span>2<span style="font-style: italic"></span></span><span style="font-style: italic"></span>)<span style="font-style: italic"></span>
and <span class="RktSym">inc</span>&rsquo;s is <span style="font-style: italic">O</span>(<span style="font-style: italic"></span>2<span style="font-style: italic"></span><span style="vertical-align: super; font-size: 80%"><span style="font-style: italic">n</span></span><span style="font-style: italic"></span>)<span style="font-style: italic"></span>&#8212;<wbr></wbr>again because <span style="font-style: italic">n</span><span style="vertical-align: super; font-size: 80%"><span style="font-style: italic"></span>2<span style="font-style: italic"></span></span><span style="font-style: italic"></span> is
short-hand for the function <span style="font-style: italic">sqr</span>(<span style="font-style: italic">n</span>)<span style="font-style: italic"> = n</span><span style="vertical-align: super; font-size: 80%"><span style="font-style: italic"></span>2<span style="font-style: italic"></span></span><span style="font-style: italic"></span> and <span style="font-style: italic"></span>2<span style="font-style: italic"></span><span style="vertical-align: super; font-size: 80%"><span style="font-style: italic">n</span></span><span style="font-style: italic"></span> is short
for <span style="font-style: italic">expt</span>(<span style="font-style: italic">n</span>)<span style="font-style: italic"> = </span>2<span style="font-style: italic"></span><span style="vertical-align: super; font-size: 80%"><span style="font-style: italic">n</span></span><span style="font-style: italic"></span>.</p><p>Stop! What does it mean to say that a function&rsquo;s performance is
<span style="font-style: italic">O</span>(<span style="font-style: italic"></span>1<span style="font-style: italic"></span>)<span style="font-style: italic"></span>?</p><p><a name="(counter._(exercise._ex~3abig-o1))"></a><span style="font-weight: bold">Exercise</span>&nbsp;486. In the first subsection, we stated that the function
<span style="font-style: italic">f</span>(<span style="font-style: italic">n</span>)<span style="font-style: italic"> = n</span><span style="vertical-align: super; font-size: 80%"><span style="font-style: italic"></span>2<span style="font-style: italic"></span></span><span style="font-style: italic"> + n</span> belongs to the class <span style="font-style: italic">O</span>(<span style="font-style: italic">n</span><span style="vertical-align: super; font-size: 80%"><span style="font-style: italic"></span>2<span style="font-style: italic"></span></span><span style="font-style: italic"></span>)<span style="font-style: italic"></span>. Determine the
pair of numbers <span style="font-style: italic">c</span> and <span style="font-style: italic">bigEnough</span> that verify this claim. <a href="i5-6.html#%28counter._%28exercise._ex~3abig-o1%29%29" class="ex-end" data-pltdoc="x"></a></p><p><a name="(counter._(exercise._ex~3abig-o2))"></a><span style="font-weight: bold">Exercise</span>&nbsp;487. Consider the functions <span style="font-style: italic">f</span>(<span style="font-style: italic">n</span>)<span style="font-style: italic"> = </span>2<span style="font-style: italic"></span><span style="vertical-align: super; font-size: 80%"><span style="font-style: italic">n</span></span><span style="font-style: italic"></span> and
<span style="font-style: italic">g</span>(<span style="font-style: italic">n</span>)<span style="font-style: italic"> = </span>1<span style="font-style: italic"></span>0<span style="font-style: italic"></span>0<span style="font-style: italic"></span>0<span style="font-style: italic"> n</span>. Show that <span style="font-style: italic">g</span> belongs to <span style="font-style: italic">O</span>(<span style="font-style: italic">f</span>)<span style="font-style: italic"></span>,
which means that <span style="font-style: italic">f</span> is, abstractly speaking, more (or at least
equally) expensive than <span style="font-style: italic">g</span>. If the input size is guaranteed to be
between 3 and 12, which function is better? <a href="i5-6.html#%28counter._%28exercise._ex~3abig-o2%29%29" class="ex-end" data-pltdoc="x"></a></p><p><a name="(counter._(exercise._ex~3abig-o3))"></a><span style="font-weight: bold">Exercise</span>&nbsp;488. Compare <img src="pict_271.png" alt="image" width="83" height="12"/> and <img src="pict_272.png" alt="image" width="53" height="13"/>. Does <span style="font-style: italic">f</span> belong to <span style="font-style: italic">O</span>(<span style="font-style: italic">g</span>)<span style="font-style: italic"></span> or <span style="font-style: italic">g</span> to <span style="font-style: italic">O</span>(<span style="font-style: italic">f</span>)<span style="font-style: italic">?</span> <a href="i5-6.html#%28counter._%28exercise._ex~3abig-o3%29%29" class="ex-end" data-pltdoc="x"></a></p><h3><a name="(part._.Why_.Do_.Programs_.Use_.Predicates_and_.Selectors_)"></a>Why Do Programs Use Predicates and Selectors?</h3><p><div class="SIntrapara">The notion of &ldquo;on the order of&rdquo; explains why the <a name="(idx._(gentag._699))"></a>design recipes produce
both well-organized and &ldquo;performant&rdquo; programs. We illustrate this
insight with a single example, the design of a program that searches for
a number in a list of numbers. Here are the signature, the purpose
statement, and examples formulated as tests:
</div><div class="SIntrapara"><blockquote class="SCodeFlow"><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td><span class="RktCmt">;</span><span class="RktCmt">&nbsp;</span><a href="part_one.html#%28tech._number%29" class="techoutside" data-pltdoc="x"><span class="techinside">Number</span></a><span class="RktCmt"> [</span><a href="part_three.html#%28tech._sim-dd._list._of%29" class="techoutside" data-pltdoc="x"><span class="techinside">List-of</span></a><span class="RktCmt"> </span><a href="part_one.html#%28tech._number%29" class="techoutside" data-pltdoc="x"><span class="techinside">Number</span></a><span class="RktCmt">] -&gt; </span><a href="part_one.html#%28tech._boolean%29" class="techoutside" data-pltdoc="x"><span class="techinside">Boolean</span></a></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt">&nbsp;</span><span class="RktCmt">is </span><span class="RktSym">x</span><span class="RktCmt"> in </span><span class="RktSym">l</span></td></tr><tr><td><span class="hspace">&nbsp;</span></td></tr><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._check-expect%29%29" class="RktStxLink" data-pltdoc="x">check-expect</a></span><span class="hspace">&nbsp;</span><span class="RktPn">(</span><span class="RktSym">search</span><span class="hspace">&nbsp;</span><span class="RktVal">0</span><span class="hspace">&nbsp;</span><span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">3</span><span class="hspace">&nbsp;</span><span class="RktVal">2</span><span class="hspace">&nbsp;</span><span class="RktVal">1</span><span class="hspace">&nbsp;</span><span class="RktVal">0</span><span class="RktVal">)</span><span class="RktPn">)</span><span class="hspace">&nbsp;</span><span class="RktVal">#true</span><span class="RktPn">)</span></td></tr><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._check-expect%29%29" class="RktStxLink" data-pltdoc="x">check-expect</a></span><span class="hspace">&nbsp;</span><span class="RktPn">(</span><span class="RktSym">search</span><span class="hspace">&nbsp;</span><span class="RktVal">4</span><span class="hspace">&nbsp;</span><span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">3</span><span class="hspace">&nbsp;</span><span class="RktVal">2</span><span class="hspace">&nbsp;</span><span class="RktVal">1</span><span class="hspace">&nbsp;</span><span class="RktVal">0</span><span class="RktVal">)</span><span class="RktPn">)</span><span class="hspace">&nbsp;</span><span class="RktVal">#false</span><span class="RktPn">)</span></td></tr></table></blockquote></div></p><p><div class="SIntrapara">Here are two definitions that live up to these expectations: <a name="(idx._(gentag._700))"></a> <a name="(idx._(gentag._701))"></a>
</div><div class="SIntrapara"><blockquote class="SVInsetFlow"><table cellspacing="0" cellpadding="0"><tr><td><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._define%29%29" class="RktStxLink" data-pltdoc="x">define</a></span><span class="hspace">&nbsp;</span><span class="RktPn">(</span><span class="RktSym">searchL</span><span class="hspace">&nbsp;</span><span class="RktSym">x</span><span class="hspace">&nbsp;</span><span class="RktSym">l</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace">&nbsp;&nbsp;</span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._cond%29%29" class="RktStxLink" data-pltdoc="x">cond</a></span></td></tr><tr><td><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="RktPn">[</span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._empty~3f%29%29" class="RktValLink" data-pltdoc="x">empty?</a></span><span class="hspace">&nbsp;</span><span class="RktSym">l</span><span class="RktPn">)</span><span class="hspace">&nbsp;</span><span class="RktVal">#false</span><span class="RktPn">]</span></td></tr><tr><td><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="RktPn">[</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._else%29%29" class="RktStxLink" data-pltdoc="x">else</a></span></td></tr><tr><td><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._or%29%29" class="RktStxLink" data-pltdoc="x">or</a></span><span class="hspace">&nbsp;</span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._~3d%29%29" class="RktValLink" data-pltdoc="x">=</a></span><span class="hspace">&nbsp;</span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._first%29%29" class="RktValLink" data-pltdoc="x">first</a></span><span class="hspace">&nbsp;</span><span class="RktSym">l</span><span class="RktPn">)</span><span class="hspace">&nbsp;</span><span class="RktSym">x</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="RktPn">(</span><span class="RktSym">searchL</span></td></tr><tr><td><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="RktSym">x</span><span class="hspace">&nbsp;</span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._rest%29%29" class="RktValLink" data-pltdoc="x">rest</a></span><span class="hspace">&nbsp;</span><span class="RktSym">l</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">]</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr></table></td><td><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._define%29%29" class="RktStxLink" data-pltdoc="x">define</a></span><span class="hspace">&nbsp;</span><span class="RktPn">(</span><span class="RktSym">searchS</span><span class="hspace">&nbsp;</span><span class="RktSym">x</span><span class="hspace">&nbsp;</span><span class="RktSym">l</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace">&nbsp;&nbsp;</span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._cond%29%29" class="RktStxLink" data-pltdoc="x">cond</a></span></td></tr><tr><td><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="RktPn">[</span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._~3d%29%29" class="RktValLink" data-pltdoc="x">=</a></span><span class="hspace">&nbsp;</span><span class="RktPn">(</span><span class="RktSym">length</span><span class="hspace">&nbsp;</span><span class="RktSym">l</span><span class="RktPn">)</span><span class="hspace">&nbsp;</span><span class="RktVal">0</span><span class="RktPn">)</span><span class="hspace">&nbsp;</span><span class="RktVal">#false</span><span class="RktPn">]</span></td></tr><tr><td><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="RktPn">[</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._else%29%29" class="RktStxLink" data-pltdoc="x">else</a></span></td></tr><tr><td><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._or%29%29" class="RktStxLink" data-pltdoc="x">or</a></span><span class="hspace">&nbsp;</span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._~3d%29%29" class="RktValLink" data-pltdoc="x">=</a></span><span class="hspace">&nbsp;</span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._first%29%29" class="RktValLink" data-pltdoc="x">first</a></span><span class="hspace">&nbsp;</span><span class="RktSym">l</span><span class="RktPn">)</span><span class="hspace">&nbsp;</span><span class="RktSym">x</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="RktPn">(</span><span class="RktSym">searchS</span></td></tr><tr><td><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="RktSym">x</span><span class="hspace">&nbsp;</span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._rest%29%29" class="RktValLink" data-pltdoc="x">rest</a></span><span class="hspace">&nbsp;</span><span class="RktSym">l</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">]</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr></table></td></tr></table></blockquote></div><div class="SIntrapara">The design of the program on the left follows the design recipe. In
particular, the development of the template calls for the use of
<a name="(idx._(gentag._702))"></a>structural predicates per clause in the data definition. Following this
advice yields a conditional program whose first <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._cond%29%29" class="RktStxLink" data-pltdoc="x">cond</a></span> line deals
with empty lists and whose second one deals with all others. The question in the
first <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._cond%29%29" class="RktStxLink" data-pltdoc="x">cond</a></span> line uses <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._empty~3f%29%29" class="RktValLink" data-pltdoc="x">empty?</a></span> and the second one uses
<span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._cons~3f%29%29" class="RktValLink" data-pltdoc="x">cons?</a></span> or <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._else%29%29" class="RktStxLink" data-pltdoc="x">else</a></span>.</div></p><p>The design of <span class="RktSym">searchS</span> fails to live up to the <a name="(idx._(gentag._703))"></a>structural
design<span class="refelem"><span class="refcolumn"><span class="refcontent">It really uses generative recursion.</span></span></span> recipe. It
instead takes inspiration from the idea that lists are containers that
have a size. Hence, a program can check this size for <span class="RktVal">0</span>, which is
equivalent to checking for emptiness.</p><p>Although this idea is functionally correct, it makes the assumption that
the cost of <span class="stt">*SL</span>-provided operations is a fixed constant. If
<span class="RktSym">length</span> is more like <span class="RktSym">how-many</span>, however, <span class="RktSym">searchS</span>
is going to be slower than <span class="RktSym">searchL</span>. Using our new terminology,
<span class="RktSym">searchL</span> is using <span style="font-style: italic">O</span>(<span style="font-style: italic">n</span>)<span style="font-style: italic"></span> recursive steps while
<span class="RktSym">searchS</span> needs <span style="font-style: italic">O</span>(<span style="font-style: italic">n</span><span style="vertical-align: super; font-size: 80%"><span style="font-style: italic"></span>2<span style="font-style: italic"></span></span><span style="font-style: italic"></span>)<span style="font-style: italic"></span> steps for a list of <span style="font-style: italic">n</span>
items. In short, using arbitrary <span class="stt">*SL</span> operations to formulate conditions
may shift performance from one class of functions to one that is much
worse.</p><p><div class="SIntrapara">Let&rsquo;s wrap up this intermezzo with an experiment that checks whether
<span class="RktSym">length</span> is a constant-time function or whether it consumes time
proportionally to the length of the given list. The easiest way is to
define a program that creates a long list and determines how much time
each version of the search program takes: <a name="(idx._(gentag._704))"></a>
</div><div class="SIntrapara"><blockquote class="SCodeFlow"><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td><span class="RktCmt">;</span><span class="RktCmt">&nbsp;</span><a href="part_two.html#%28tech._n%29" class="techoutside" data-pltdoc="x"><span class="techinside">N</span></a><span class="RktCmt"> -&gt; [</span><a href="part_three.html#%28tech._sim-dd._list%29" class="techoutside" data-pltdoc="x"><span class="techinside">List</span></a><span class="RktCmt"> </span><a href="part_one.html#%28tech._number%29" class="techoutside" data-pltdoc="x"><span class="techinside">Number</span></a><span class="RktCmt"> </span><a href="part_one.html#%28tech._number%29" class="techoutside" data-pltdoc="x"><span class="techinside">Number</span></a><span class="RktCmt">]</span></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt">&nbsp;</span><span class="RktCmt">how long do </span><span class="RktSym">searchS</span><span class="RktCmt"> and </span><span class="RktSym">searchL</span><span class="RktCmt"> take </span></td></tr><tr><td><span class="RktCmt">;</span><span class="RktCmt">&nbsp;</span><span class="RktCmt">to look for </span><span class="RktSym">n</span><span class="RktCmt"> in </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._list%29%29" class="RktValLink" data-pltdoc="x">list</a></span><span class="stt"> </span><span class="RktVal">0</span><span class="stt"> </span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._......%29%29" class="RktStxLink" data-pltdoc="x">...</a></span><span class="stt"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._-%29%29" class="RktValLink" data-pltdoc="x"><span class="nobreak">-</span></a></span><span class="stt"> </span><span class="RktSym">n</span><span class="stt"> </span><span class="RktVal">1</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._define%29%29" class="RktStxLink" data-pltdoc="x">define</a></span><span class="hspace">&nbsp;</span><span class="RktPn">(</span><span class="RktSym">timing</span><span class="hspace">&nbsp;</span><span class="RktSym">n</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace">&nbsp;&nbsp;</span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._local%29%29" class="RktStxLink" data-pltdoc="x">local</a></span><span class="hspace">&nbsp;</span><span class="RktPn">(</span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._define%29%29" class="RktStxLink" data-pltdoc="x">define</a></span><span class="hspace">&nbsp;</span><span class="RktSym">long-list</span></td></tr><tr><td><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._build-list%29%29" class="RktValLink" data-pltdoc="x">build-list</a></span><span class="hspace">&nbsp;</span><span class="RktSym">n</span><span class="hspace">&nbsp;</span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._lambda%29%29" class="RktStxLink" data-pltdoc="x">lambda</a></span><span class="hspace">&nbsp;</span><span class="RktPn">(</span><span class="RktSym">x</span><span class="RktPn">)</span><span class="hspace">&nbsp;</span><span class="RktSym">x</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._list%29%29" class="RktValLink" data-pltdoc="x">list</a></span></td></tr><tr><td><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._time%29%29" class="RktStxLink" data-pltdoc="x">time</a></span><span class="hspace">&nbsp;</span><span class="RktPn">(</span><span class="RktSym">searchS</span><span class="hspace">&nbsp;</span><span class="RktSym">n</span><span class="hspace">&nbsp;</span><span class="RktSym">long-list</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="RktPn">(</span><span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28form._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._time%29%29" class="RktStxLink" data-pltdoc="x">time</a></span><span class="hspace">&nbsp;</span><span class="RktPn">(</span><span class="RktSym">searchL</span><span class="hspace">&nbsp;</span><span class="RktSym">n</span><span class="hspace">&nbsp;</span><span class="RktSym">long-list</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr></table></blockquote></div><div class="SIntrapara">Now run this program on <span class="RktVal">10000</span> and <span class="RktVal">20000</span>.
If <span class="RktSym">length</span> is like <span class="RktSym"><a href="https://docs.racket-lang.org/htdp-langs/intermediate-lam.html#%28def._htdp-intermediate-lambda._%28%28lib._lang%2Fhtdp-intermediate-lambda..rkt%29._empty~3f%29%29" class="RktValLink" data-pltdoc="x">empty?</a></span>, the times for the second run
will be roughly twice those of the first one; otherwise, the time for
<span class="RktSym">searchS</span> will increase dramatically.</div></p><p>Stop! Conduct the experiment.</p><p>Assuming you have completed the experiment, you now know that
<span class="RktSym">length</span> takes time proportionally to the size of the given list.
The &ldquo;S&rdquo; in <span class="RktSym">searchS</span> stands for &ldquo;squared&rdquo; because its running
time is <span style="font-style: italic">O</span>(<span style="font-style: italic">n</span><span style="vertical-align: super; font-size: 80%"><span style="font-style: italic"></span>2<span style="font-style: italic"></span></span><span style="font-style: italic"></span>)<span style="font-style: italic"></span>. But don&rsquo;t jump to the conclusion that
this<span class="refelem"><span class="refcolumn"><span class="refcontent">See <a href="part_six.html#%28part._sec~3amore-accu-mc%29" data-pltdoc="x">Data Representations with Accumulators</a> for how other languages
track the size of a container.</span></span></span> kind of reasoning holds for every
programming language you will encounter. Many deal with containers
differently than <span class="stt">*SL</span>. Understanding how this is done requires one more
design concept, accumulators, the concern of the final part of this book.</p><h3><a name="(part._i5-6-fake)"></a></h3><div class="navsetbottom"><span class="navleft"><div class="nosearchform"></div>&nbsp;&nbsp;<span class="tocsettoggle">&nbsp;&nbsp;<a href="javascript:void(0);" title="show/hide table of contents" onclick="TocsetToggle();">contents</a></span></span><span class="navright">&nbsp;&nbsp;<a href="part_five.html" title="backward to &quot;V Generative Recursion&quot;" data-pltdoc="x">&larr; prev</a>&nbsp;&nbsp;<a href="index.html" title="up to &quot;How to Design Programs, Second Edition&quot;" data-pltdoc="x">up</a>&nbsp;&nbsp;<a href="part_six.html" title="forward to &quot;VI Accumulators&quot;" data-pltdoc="x">next &rarr;</a></span>&nbsp;</div></div></div><div id="contextindicator">&nbsp;</div></body></html>