Tải bản đầy đủ - 0 (trang)
Chapter 3. The Most Beautiful Code I Never Wrote

Chapter 3. The Most Beautiful Code I Never Wrote

Tải bản đầy đủ - 0trang

3.TheMostBeautifulCodeINever

Wrote

JonBentley

Ionceheardamasterprogrammerpraisedwiththephrase,"Headdsfunction



bydeletingcode."AntoinedeSaint-Exupéry,theFrenchwriter

andaviator,expressedthissentimentmoregenerallywhenhe

said,"Adesignerknowshehasachievedperfectionnotwhen

thereisnothinglefttoadd,butwhenthereisnothingleftto

takeaway."Insoftware,themostbeautifulcode,themost

beautifulfunctions,andthemostbeautifulprogramsare

sometimesnotthereatall.

Itis,ofcourse,difficulttotalkaboutthingsthataren'tthere.

Thischapterattemptsthisdauntingtaskbypresentinganovel

analysisoftheruntimeoftheclassicQuicksortprogram.The

firstsectionsetsthestagebyreviewingQuicksortfroma

personalperspective.Thesubsequentsectionisthemeatofthis

chapter.We'llstartbyaddingonecountertotheprogram,then

manipulatethecodetomakeitsmallerandsmallerandyet

moreandmorepowerfuluntiljustafewlinesofcode

completelycaptureitsaverageruntime.Thethirdsection

summarizesthetechniques,andpresentsaparticularlysuccinct

analysisofthecostofbinarysearchtrees.Thefinaltwo

sectionsdrawinsightsfromthechaptertohelpyouwritemore

elegantprograms.



3.1.TheMostBeautifulCodeIEver

Wrote

WhenGregWilsonfirstdescribedtheideaofthisbook,Iasked

myselfwhatwasthemostbeautifulcodeIhadeverwritten.

Afterthisdeliciousquestionrolledaroundmybrainforthe

betterpartofaday,Irealizedthattheanswerwaseasy:

Quicksort.Unfortunately,theonequestionhasthreedifferent



answers,dependingonpreciselyhowitisphrased.

Iwrotemythesisondivide-and-conqueralgorithms,andfound

thatC.A.R.Hoare'sQuicksort("Quicksort,"ComputerJournal5)

isundeniablythegranddaddyofthemall.Itisabeautiful

algorithmforafundamentalproblemthatcanbeimplemented

inelegantcode.Ilovedthealgorithm,butIalwaystiptoed

arounditsinnermostloop.Ioncespenttwodaysdebugginga

complexprogramthatwasbasedonthatloop,andforyearsI

carefullycopiedthatcodewheneverIneededtoperforma

similartask.Itsolvedmyproblems,butIdidn'treally

understandit.

IeventuallylearnedanelegantpartitioningschemefromNico

Lomuto,andwasfinallyabletowriteaQuicksortthatIcould

understandandevenprovecorrect.WilliamStrunkJr.'s

observationthat"vigorouswritingisconcise"appliestocodeas

wellastoEnglish,soIfollowedhisadmonitionto"omit

needlesswords"(TheElementsofStyle).Ifinallyreduced

approximately40linesofcodetoanevendozen.Soifthe

questionis,"Whatisthemostbeautifulsmallpieceofcodethat

you'veeverwritten?"myansweristheQuicksortfrommybook

ProgrammingPearls,SecondEdition(Addison-Wesley).This

Quicksortfunction,implementedinC,isshowninExample3-1.

We'llfurtherstudyandrefinethisexampleinthenextsection.

Example3-1.Quicksortfunction

voidquicksort(intl,intu)

{inti,m;

if(l>=u)return;

swap(l,randint(l,u));

m=l;

for(i=l+1;i<=u;i++)

if(x[i]
swap(++m,i);

swap(l,m);



quicksort(l,m-1);

quicksort(m+1,u);

}



Thiscodesortsaglobalarrayx[n]whencalledwiththe

argumentsquicksort(0,n-1).Thetwoparametersofthe

functionaretheindexesofthesubarraytobesorted:lfor

loweranduforupper.Thecallswap(i,j)exchangesthe

contentsofx[i]andx[j].Thefirstswaprandomlychoosesa

partitioningelementuniformlyselectedbetweenlandu.

ProgrammingPearlscontainsadetailedderivationandproofof

correctnessforthequicksortfunction.Throughouttherestof

thischapter,I'llassumethatthereaderisfamiliarwith

Quicksorttothelevelpresentedinthatdescriptionandinmost

elementaryalgorithmstextbooks.

Ifyouchangethequestionto,"Whatisthemostbeautifulpiece

ofcodethatyou'vewrittenthatwaswidelyused?"myansweris

againaQuicksort.AnarticleIwrotewithM.D.McIlroy

("Engineeringasortfunction,"Software–Practiceand

Experience,Vol.23,No.11)describesaseriousperformance

buginthevenerableUnixqsortfunction.Wesetouttobuilda

newClibrarysortfunction,andconsideredmanydifferent

algorithmsforthetask,includingMergeSortandHeapSort.

Aftercomparingseveralpossibleimplementations,wesettled

onaversionoftheQuicksortalgorithm.Thatpaperdescribes

howweengineeredanewfunctionthatwasclearer,faster,and

morerobustthanitscompetitors—partlybecauseitwassmaller.

GordonBell'ssageadviceprovedtrue:"Thecheapest,fastest,

andmostreliablecomponentsofacomputersystemarethose

thataren'tthere."Thatfunctionhasnowbeenwidelyusedfor

overadecadewithnoreportsoffailure.

Consideringthegainsthatcouldbeachievedbyreducingcode

size,Ifinallyaskedmyselfathirdvariantofthequestionthat



beganthischapter."Whatisthemostbeautifulcodethatyou

neverwrote?"HowwasIabletoaccomplishagreatdealwith

verylittle?TheanswerwasonceagainrelatedtoQuicksort,

specifically,theanalysisofitsperformance.Thenextsection

tellsthattale.







TheMostBeautifulCodeINeverWrote>TheMost

BeautifulCodeIEverWrote



3.TheMostBeautifulCodeINever

Wrote

JonBentley

Ionceheardamasterprogrammerpraisedwiththephrase,"Headdsfunction



bydeletingcode."AntoinedeSaint-Exupéry,theFrenchwriter

andaviator,expressedthissentimentmoregenerallywhenhe

said,"Adesignerknowshehasachievedperfectionnotwhen

thereisnothinglefttoadd,butwhenthereisnothingleftto

takeaway."Insoftware,themostbeautifulcode,themost

beautifulfunctions,andthemostbeautifulprogramsare

sometimesnotthereatall.

Itis,ofcourse,difficulttotalkaboutthingsthataren'tthere.

Thischapterattemptsthisdauntingtaskbypresentinganovel

analysisoftheruntimeoftheclassicQuicksortprogram.The

firstsectionsetsthestagebyreviewingQuicksortfroma

personalperspective.Thesubsequentsectionisthemeatofthis

chapter.We'llstartbyaddingonecountertotheprogram,then

manipulatethecodetomakeitsmallerandsmallerandyet

moreandmorepowerfuluntiljustafewlinesofcode

completelycaptureitsaverageruntime.Thethirdsection

summarizesthetechniques,andpresentsaparticularlysuccinct

analysisofthecostofbinarysearchtrees.Thefinaltwo

sectionsdrawinsightsfromthechaptertohelpyouwritemore

elegantprograms.



3.1.TheMostBeautifulCodeIEver

Wrote

WhenGregWilsonfirstdescribedtheideaofthisbook,Iasked

myselfwhatwasthemostbeautifulcodeIhadeverwritten.

Afterthisdeliciousquestionrolledaroundmybrainforthe

betterpartofaday,Irealizedthattheanswerwaseasy:

Quicksort.Unfortunately,theonequestionhasthreedifferent



answers,dependingonpreciselyhowitisphrased.

Iwrotemythesisondivide-and-conqueralgorithms,andfound

thatC.A.R.Hoare'sQuicksort("Quicksort,"ComputerJournal5)

isundeniablythegranddaddyofthemall.Itisabeautiful

algorithmforafundamentalproblemthatcanbeimplemented

inelegantcode.Ilovedthealgorithm,butIalwaystiptoed

arounditsinnermostloop.Ioncespenttwodaysdebugginga

complexprogramthatwasbasedonthatloop,andforyearsI

carefullycopiedthatcodewheneverIneededtoperforma

similartask.Itsolvedmyproblems,butIdidn'treally

understandit.

IeventuallylearnedanelegantpartitioningschemefromNico

Lomuto,andwasfinallyabletowriteaQuicksortthatIcould

understandandevenprovecorrect.WilliamStrunkJr.'s

observationthat"vigorouswritingisconcise"appliestocodeas

wellastoEnglish,soIfollowedhisadmonitionto"omit

needlesswords"(TheElementsofStyle).Ifinallyreduced

approximately40linesofcodetoanevendozen.Soifthe

questionis,"Whatisthemostbeautifulsmallpieceofcodethat

you'veeverwritten?"myansweristheQuicksortfrommybook

ProgrammingPearls,SecondEdition(Addison-Wesley).This

Quicksortfunction,implementedinC,isshowninExample3-1.

We'llfurtherstudyandrefinethisexampleinthenextsection.

Example3-1.Quicksortfunction

voidquicksort(intl,intu)

{inti,m;

if(l>=u)return;

swap(l,randint(l,u));

m=l;

for(i=l+1;i<=u;i++)

if(x[i]
swap(++m,i);

swap(l,m);



quicksort(l,m-1);

quicksort(m+1,u);

}



Thiscodesortsaglobalarrayx[n]whencalledwiththe

argumentsquicksort(0,n-1).Thetwoparametersofthe

functionaretheindexesofthesubarraytobesorted:lfor

loweranduforupper.Thecallswap(i,j)exchangesthe

contentsofx[i]andx[j].Thefirstswaprandomlychoosesa

partitioningelementuniformlyselectedbetweenlandu.

ProgrammingPearlscontainsadetailedderivationandproofof

correctnessforthequicksortfunction.Throughouttherestof

thischapter,I'llassumethatthereaderisfamiliarwith

Quicksorttothelevelpresentedinthatdescriptionandinmost

elementaryalgorithmstextbooks.

Ifyouchangethequestionto,"Whatisthemostbeautifulpiece

ofcodethatyou'vewrittenthatwaswidelyused?"myansweris

againaQuicksort.AnarticleIwrotewithM.D.McIlroy

("Engineeringasortfunction,"Software–Practiceand

Experience,Vol.23,No.11)describesaseriousperformance

buginthevenerableUnixqsortfunction.Wesetouttobuilda

newClibrarysortfunction,andconsideredmanydifferent

algorithmsforthetask,includingMergeSortandHeapSort.

Aftercomparingseveralpossibleimplementations,wesettled

onaversionoftheQuicksortalgorithm.Thatpaperdescribes

howweengineeredanewfunctionthatwasclearer,faster,and

morerobustthanitscompetitors—partlybecauseitwassmaller.

GordonBell'ssageadviceprovedtrue:"Thecheapest,fastest,

andmostreliablecomponentsofacomputersystemarethose

thataren'tthere."Thatfunctionhasnowbeenwidelyusedfor

overadecadewithnoreportsoffailure.

Consideringthegainsthatcouldbeachievedbyreducingcode

size,Ifinallyaskedmyselfathirdvariantofthequestionthat



beganthischapter."Whatisthemostbeautifulcodethatyou

neverwrote?"HowwasIabletoaccomplishagreatdealwith

verylittle?TheanswerwasonceagainrelatedtoQuicksort,

specifically,theanalysisofitsperformance.Thenextsection

tellsthattale.







TheMostBeautifulCodeINeverWrote>MoreandMore

withLessandLess



3.2.MoreandMorewithLessandLess

Quicksortisanelegantalgorithmthatlendsitselftosubtle

analysis.Around1980,IhadawonderfuldiscussionwithTony

Hoareaboutthehistoryofhisalgorithm.Hetoldmethatwhen

hefirstdevelopedQuicksort,hethoughtitwastoosimpleto

publish,andonlywrotehisclassic"Quicksort"paperafterhe

wasabletoanalyzeitsexpectedruntime.

Itiseasytoseethatintheworstcase,Quicksortmighttake

aboutn2timetosortanarrayofnelements.Inthebestcase,

itchoosesthemedianvalueasapartitioningelement,and

thereforesortsanarrayinaboutnlgncomparisons.So,how

manycomparisonsdoesituseontheaverageforarandom

arrayofndistinctvalues?

Hoare'sanalysisofthisquestionisbeautiful,butunfortunately

overthemathematicalheadsofmanyprogrammers.WhenI

taughtQuicksorttoundergraduates,Iwasfrustratedthatmany

justdidn't"get"theproof,evenaftersincereeffort.We'llnow

attackthatproblemexperimentally.We'llstartwithHoare's

program,andeventuallyendupwithananalysisclosetohis.

OurtaskistomodifyExample3-1oftherandomizingQuicksort

codetoanalyzetheaveragenumberofcomparisonsusedto

sortanarrayofdistinctinputs.Wewillalsoattempttogain

maximuminsightwithminimalcode,runtime,andspace.

Todeterminetheaveragenumberofcomparisons,wefirst

augmenttheprogramtocountthem.Todothis,weincrement

thevariablecompsbeforethecomparisonintheinnerloop

(Example3-2).

Example3-2.Quicksortinnerloopinstrumentedtocount



comparisons

for(i=l+1;i<=u;i++){

comps++;

if(x[i]
swap(++m,i);

}



Ifweruntheprogramforonevalueofn,we'llseehowmany

comparisonsthatparticularruntakes.Ifwerepeatthatfor

manyrunsovermanyvaluesofn,andanalyzetheresults

statistically,we'llobservethat,onaverage,Quicksorttakes

about1.4nlgncomparisonstosortnelements.

Thatisn'tabadwaytogaininsightintothebehaviorofa

program.Thirteenlinesofcodeandafewexperimentscan

revealalot.AfamousquoteattributedtowriterssuchasBlaise

PascalandT.S.Eliotstatesthat,"IfIhadmoretime,Iwould

havewrittenyouashorterletter."Wehavethetime,solet's

experimentwiththecodetoattempttocreateashorter(and

better)program.

We'llplaythegameofspeedingupthatexperiment,tryingto

increasestatisticalaccuracyandprogramminginsight.Because

theinnerloopalwaysmakespreciselyu-lcomparisons,wecan

maketheprogramatinybitfasterbycountingthose

comparisonsinasingleoperationoutsidetheloop.Thischange

yieldstheQuicksortshowninExample3-3.

Example3-3.Quicksortinnerloopwithincrementmoved

outofloop

comps+=u-l;

for(i=l+1;i<=u;i++)

if(x[i]


Tài liệu bạn tìm kiếm đã sẵn sàng tải về

Chapter 3. The Most Beautiful Code I Never Wrote

Tải bản đầy đủ ngay(0 tr)

×