Вы находитесь на странице: 1из 7

Howtomakeyour.

NETapplications
perform
Technicalpaper
WrittenbyJamesMoore,RedGateSoftwareLtd

ingeniouslysimpletoolsfor.NET

Howtomakeyour.NETapplicationsperform

Introduction
Becauseoftoday'shighprocessorspeeds,andthelargeamountofavailablememory,many
programmersseemtoignorethelimitationsontheseresourcesinapplications.
Thiscanoftenleadtoscalabilityandperformanceproblemsthatcanoftenbesolvedwith
verylittledifficulty.Thispaperdiscussescommonpitfallsandproblemswhencreating
applicationsin.NET.Wewillcoversomenomenclaturefirst,thenpresentseveralcommon
issuesthatwehavecomeacrossinawidevarietyofapplications.Wewillthendescribe
somecommonwaysofsolvingtheseproblems.
Bewareofoptimizingneedlessly.Youarebetteroffwritingreadablecode,thenfocusing
youreffortsonoptimizingonlythosepartsthatneeditthisisjustastruewithJustInTime
(JIT)compiledplatforms,suchas.NETaswithnativecode.
Ifweoveroptimizeourcode,werisklimitingtheabilityofthecompilertoperformcompiler
optimizations,suchasloopinterchange,1 therebyleadingtoadecreaseinperformance,as
thecompilermayselectdifferentoptimizationsdependingonplatform2.
Inmyexperience,itisbesttoensureyouhaveascalablearchitecture,andleave
optimizationforasubsequentstageinwhichyoucanidentify,measure,andfixthose
performancehotspots.

AbigOh
YoumayhavecomeacrossbigOnotation3 before.Itisusedtodescribehowanalgorithm
employsresources(timeandmemory)dependingonthesizeofitsinput.Ifafunctionhasa
timecomplexityofO(n2),thenweimplythatafternissufficientlylarge,theamountoftime
spentinthefunctiongrowsinproportiontothesquareofthesizeoftheinputbutwhennis
small,thisisnotnecessarilythecase.
Let'shavealookatthefollowingfunction:
1:
staticvoidSomeFunction(int[]array)
2:{
3:
Thread.Sleep(100000)
4:
5:
for(inti=0i<array.Lengthi++)
6:{
7:
for(intj=0j<array.Lengthj++)
8:{
9:
Thread.Sleep(10)
10:}
11:}
12:}

Seehttp://en.wikipedia.org/wiki/Compiler_optimizationforinformationaboutthewonderfulthings
yourcompilercandoforyou.
2
Foragreatoverviewofdifferentarchitecturesandtheirbehaviors,getacopyofComputer
Architecture,AQuantitativeApproachbyJohnL.HennessyandDavidA.Patterson.
3
AlsoknownasBigOh,Landaunotationorasymptoticnotation.

Howtomakeyour.NETapplicationsperform
ThisfunctionhasatimecomplexityofO(n2).Ifwepassinanarrayof1element,thenthe
functionwillspendlongestinthesleeponline3ofourfunctionandthisisstilltrueifwepass
a100elementarray.However,ifwepassina1,000elementarray,thesameamountoftime
isspentinline9asline3.
Asthenumberofelementsinthearraygrowsbeyond1,000,thesleeponline9becomes
moreandmoredominantandthesleeponline3losesitsinfluenceontheruntimeofthe
function.
Thetablebelowoutlinesseveralcommonfunctioncomplexities,illustratinghowtheygrow
withthesizeoftheinput.

1
10
50
100
1000
10000
1000000

O(1) O(lgN)
O(n) O(nlgn)
O(n2)
O(n3)
1
1
1
1
1
1
1
3
10
33
100
1000
1
6
50
282
2500
125000
1
7
100
664
10000
1000000
1
10
1000
9966
1000000 1000000000
1
13
10000
132877 100000000
1012
12
1
20 1000000 19931569
10
1018

Iwasgoingtodrawagraphofthistable,butyouwouldonlyhavebeenabletoseethelines
ofO(n3)orO(n2),astheygrowsomuchmorerapidlythantheothers.
Sofar,wehavebeentalkingabouttimecomplexities,butitisimportanttorememberthat
thesamecanalsobetrueofmemoryusage.
Youwilloftenfindthat,todecreaseafunction'stimecomplexity,youneedtoincreaseits
memorycomplexity.CanyoucomeupwithafunctionwithanO(1)timecomplexity(i.e.the
function'sexecutiontimedoesnotvarywiththesizeoftheinput),andafunctionwithan
O(1)memorycomplexity,totellifanumberunder10,000isprimeornot?Whatarethe
respectivememoryandtimecomplexities?

Getreal
SoallthiscomplexitymalarkeysoundsgoodbuthowdoIuseitinpractice?Myfunctionis
5,000linesofcode,callsotherfunctionsandhas20parametersthereisnowayIcan
figureoutitstime/memorycomplexity!
Thetruthis,youdon'tneedtofigureitoutbyhand.ThewaythatIdoitistouseaprofiler
andruntheapplicationwithonesetofinputs,thenrankthefunctionsinorderoftheir
executiontimes.ANTSProfilerismypersonalfavorite,asitissimpletouse,andit
supportslineleveltimings.Ithenchangethesizeoftheinputs,runtheprofileragain,and
rankthefunctionsoncemoreintermsoftheirexecutiontimes.
Next,Icomparethetwolistsandlookatthedifferencesinfunctionrank.Functionsthathave
moveduprelativetotheothersaretheonesthatarelikelytohavescalabilityproblems,and
canbeinvestigatedfurther.Anoteofcautionaboutthis:althoughyoudonotneedtogoto
theextremesofinputsizedifferences,youdoneedtomakesuretheyarelargeenough.
2

Howtomakeyour.NETapplicationsperform
Thinkaboutthefunctionintroducedduringthefirstpartofthisarticle.IfIweretopassina10
elementarrayanda100elementarray,the"sleep"online3isstilldominantinbothcases.If
Ipassina10elementarrayanda10,000elementarray,thenwewillseethefunction'srank
change.

Whattolookfor
Inadditiontothequicktestoutlinedintheprevioussection,overtheyearsIhavelearned,
oftenthehardway,whattoavoidandwhattolookoutforwhensolvingperformance
problems.
Loops
Themostobvioussourceofpoorperformanceisloopswherethenumberofiterations
aroundtheloopcannotbedeterminedatcompiletime.Thesegenerallyscaleasafunction
ofsomepieceofinput.
Watchoutforplaceswhereyoucallafunctioninaloopwherethatfunctionalsohasa
complexityofO(n)orabove,asyoucanthenendupwithafunctionwithacomplexityof
O(n2)withoutrealizingit.Thisisprobablythemaincauseofpoorscalabilitywith
applications.
Fixingtheproblemreallydependsonyourapplication,butIhaveoutlinedbelowthingsI
alwaysfindusefultothinkaboutwhentryingtosolveperformanceissuesrelatedtoloops.
Dolesswork
Thisseemsfairlyobvious,butistheresomewayIcanmovesomeoftheprocessingoutof
thefunctionandprecomputeorcachesomeoftheinformationIamcomputing?Thisoften
comesattheexpenseofusingsomeextramemory,sobecareful!
Divideandconquer
IstheresomewayIcansplittheinputintoparts,dotheheavyliftingonlyonpartofit,then
mergetheresultsagain?Aprimeexampleofthissortofalgorithmis"mergesort". Youwill
oftenfindthatifyoucanrewriteanalgorithmthiswayyoucanimproveperformance
significantly.
Modeling
Canyoumodelyourprobleminasimilarwaytoanotherproblem?Doesyourproblem
resemblea"sort,"orisitperhapslikeaflowoptimization?Ifso,findanalgorithmwhich
performswell,andadaptittosolveyourprobleminstead.Ifyouhaveneverlookedatit,then
IwouldsuggestgettingacopyofIntroductiontoAlgorithmsbyCormen,Leiserson,Rivest,
andStein.Itsitsonmydeskandiswellthumbed.IfinditmucheasiertofollowthanKnuth.
Dynamicprogramming
Youshouldlookatusingdynamicprogrammingwhenyourproblemcanbesplitintomultiple
subproblemsandthesesubproblemsarenotindependenti.e.eachsubproblemshares
asubsubproblemwithothersubproblems.

Howtomakeyour.NETapplicationsperform

Adivideandconquerapproachwilldomoreworkthanisnecessaryinthesecases,andcan
beoptimizedbystoringthesolutionstothesesubsubproblemsinalookuptableand
computingthemthefirsttimetheyareused,thenreusingtheresultnexttime,ratherthan
computingitagain.

Translatetheproblem
Theimplementationofasolutiontoaproblemisoftendictatedbythewaythedatais
presentedandstoredcanyouchangethewaythedataisstored?Doesthismakesolving
yourproblemanyeasier?
Ifallelsefails,fakeit
Sometimesthereisnothingyoucandoaboutperformance.Youcanonlyfactoraprime
numbersoquickly!Inthesecases,youneedtomakesurethatyoutellyouruserthatyou
aremakingprogress,andallowthemtocanceltheoperation.Usersarewillingtowaitfora
whileforresults,aslongasyoukeeptheminformed!4
Blockingfunctions
Ifyourapplicationisinteractive,asisthecasewithawebsiteor Windowsformsapplication,
beverycarefulwhencallingblockingfunctions,suchasawebservicerequestorquery
execution.Ifthewebservicerunsonaremotemachine,orthequeryhasnotbeenproperly
tuned,neverruntheseonyourmainthread.UsetheThreadPoolclassor
BackgroundWorkerclass,andshowaprogressindicatorusingthemainthread.
Databasequeriesareoneofthemostcommoncausesofpoorperformance.Theybehavein
asimilarwaytofunctioncalls,andtheirperformanceoftendependsonthenumberof
recordsinthetablesused.Checkthatyourqueriesscaleproperly,andyourdatabase's
statisticsareuptodate.Optimizingqueriescanbetrickyanditvariesfromquerytoquery,
sothebestthingisgenerallytotalktoanexpert.Luckilythereareplentyofexpertswillingto
givetheiradviceforfree,atsitessuchasSQLServerCentral.com.
4

Usabilityishugelyimportantwhenyoucannotdoanythingaboutperformance.HavealookatJacob
Nielsen'swebsite http://www.useit.com/ forlotsofinformationaboutusability.

Howtomakeyour.NETapplicationsperform
Inthepast,rewritingaqueryandensuringthatthecorrectindexeswereavailablehas
allowedmetoreduceaquery'sexecutiontimefromover30minutesto23seconds.It's
wellworthspendingafewhourstestingthescalabilityofyourqueries,andmakingsurethey
scale.
Threadscanendupinknots
AnothercommonproblemIhavecomeacrossiswheresomeonehasoptimizedtheir
programandusedmultiplethreadstoperformsomeprocessing.Thiscanworkreallywell,
butyouneedtobecarefulifyourthreadsaccessthesamedatastructuresalot.
Eachaccessshouldbemutuallyexclusive,enforcedbymutexes,otherwiseyoumay
encounterraceconditions.Howevertheacquisitionofthesemutexescancause
performanceproblemsinitself.Ifathreadholdsontoamutextoolong,itwillstopothers
accessingthesharedresource,causingthemtoblock,possiblyleadingtoperformance
issues.
Conversely,constantlyacquiringandreleasingamutexhasitsownoverhead,andcanslow
programperformancedown.
Thereareseveralsolutionstothissortofproblem(normallycalledcontentionproblems).
Batchitup
Thefirstsolutionistolookatyourprogram'saccesstothedatastructureinquestion.Can
youbatchupseveralaccessestothestructureandonlyacquirethelockonce?Ifyouare
acquiringthelock,doingsomething,andreleasingthelock,canyouchangetoacquiringthe
lock,anddoingsomethingperhaps10times,thenreleasingthelock?
Whentakingthisapproach,becarefulnottodotoomuchatonce,asthiscanblockother
threads.
Itsgoodtoshare
Iftwoormorethreadsaretryingtoreadfromthesamedatastructureatthesametime,you
mightwanttolookatusingaMutlipleReaderSingleWriterlockratherthanC#'snativelock
keyword.
Lockfree
Ifyourlevelsoflockcontentionarehighbutyouveryrarelygetupdateclashes,thinkabout
usingalockfreedatastructure.Thesearegreatinsomesituationsbut,ifyougetalarge
numberofupdateconflicts,youwillseealargedropinperformancewhileusingthem.

Howtomakeyour.NETapplicationsperform

Conclusion
Unfortunately,Icannotgiveyouhardandfastrulesforfixingperformanceproblems.Itis
reallyaquestionofrephrasingtheproblemormakingiteasiertosolve.Thinkoutofthebox
sometimes,themostunusualsolutiontoaproblemcanbethebest.
Take, forexample,Radixsort.Thisiswhere,givenalistofnumbers,say12,15,24,2,108,
1067,wesortbytheleastsignificantdigitfirst,givingus:12,2,24,15,1067,108. Wethen
sortbythetenscolumn:2,108,12,15,24,1067thehundredscolumn:2,12,15,24,1067,
108andfinallythethousandscolumn:2,12,15,24,108,1067.Thisoddsortingalgorithm
seemsfairlycounterintuitive,buthassomeveryimportantapplicationsincomputerscience.
Mostofall,payattentiontoyourapplicationsperformanceoptimizeyourcode,andtryto
negatetheusersfrustrationwhenyoucan.Thereisnothingmorefrustratingthanwaitingfor
anapplicationtofinishprocessingneedlessly!

AboutRedGateSoftware
Since1999,RedGateSoftwarehasbeendevelopingingeniouslysimpletoolsthatsimplifythe
businessofworkingwithSQLServerand.NET.Ourtools,whichincludeSQLCompare,SQL
BackupandANTSProfiler,havebecomeindustrystandardsfordevelopersandDBAsworldwide.
RedGatetoolscanbeevaluatedfree,for14days,bydownloadingthemfrom:
Http://www.redgate.com

CopyrightRedGateSoftwareLtd,Sept.2007

Вам также может понравиться