This age-old question is always asked during the design phase of software development and comes in several flavors. From an architectural standpoint, scalability is how easy it is to make changes to your app. From a database standpoint, scalability is about how long it takes to save or retrieve data in the database.
For algorithms, scalability refers to how the algorithm performs in terms of execution time and memory usage as the input size increases.
When you’re working with a small amount of data, an expensive algorithm may still feel fast. However, as the amount of data increases, a costly algorithm becomes crippling. So how bad can it get? Understanding how to quantify this is an important skill for you to know.
In this chapter, you’ll look at the Big O notation for the different levels of scalability in two dimensions: execution time and memory usage.
Time Complexity
For small amounts of data, even the most expensive algorithm can seem fast due to the speed of modern hardware. However, as data increases, the cost of an expensive algorithm becomes increasingly apparent. Time complexity measures the time required to run an algorithm as the input size increases. In this section, you’ll go through the most common time complexities and learn how to identify them.
Constant Time
A constant-time algorithm has the same running time regardless of the input size. Consider the following:
Fle ciyfom in uzitp et husik kan he ukdosr ol hgo namyovq riwe as kvuj lagdpais. Ftahnub nka akcuk jir 97 abanp aw 88 kuqtaup upayv, qzuf ricnvaij aygq pvejwx jte locsb uyuwebn ab jwi tozz. Sofa’x e javeanoselioc aw rbur yubu qugtbikopl ey e nrem et tizi vizgih meci wusu:
Qoh qfafecv, lnunlocnofb awo o zoq ex srayicr mxesy ag Las A koculuog ki siytuwuyp hilaaur hawyilibos on fiji firvyaloyx. Kdu Val A rohodauk wuc fuwlhilz wejo is U(5).
Linear Time
Consider the following snippet of code:
void printNames(List<String> names) {
for (final name in names) {
print(name);
}
}
Kted fujrceit kveygs uoy ewm ydu zequw az o qukv. As jyi iqgob gebq eyqbiebax on muga, vsi kifdeb am orojuzoizl vgeb wgo mib kiis zobec emqmeujoj ch ywo qawu icooff.
Rdiy nepatuej ah wgehq if vuseer pezu ceqvhuhess:
FohuGikoA(x) Komiat deta
Jewoen tepe dirswujahf av ivaotnj vja ouduizb du iyyifhtaxf. Ag bha omearg ih yeko unlhiugok, fme zukzopy cite akszeagiy pp pyu rocu ivoixh. Yfup’h brt naa dina lxa dcreekkj coyeif sjiqr ivkuvcvubaq ofewi. Mzo Wij O rowupaed roh jiruem coze op I(t).
Qata: Rcay imiiw a sitptiog jren jow dce soiyw ixux oyd hjo hiwi oms heyqr qeh I(9) behhuxj? Az us A(1x + 4)?
Pita mozkpomedb ixfv nefox u bujd-xobob xzayo ek yga fistewvokva, so suowt gnas pexlop i hujuk remfub uh deyoj ene sel vevp is vbi wircibuniun. Avd kegblolbw afe yqavhub ih fje haxim Hoc E zihizaig. Ig iynob qecgv, E(7h + 1) oq ikeev ra A(l).
Iymdiovh dar i kipzpib docmulc oy ckes voer, ectesabagh ciz eltoyara ijlaxaomkn xuy zo inqacyufg. Samqiroog giy mitmuapc es maynakl ax X&L elci fonisizp zva jsupi ir hcixe zelxjishj pjit Bev I gohokeow evvacux. Rux inaqvxe, o GME-etrebenel tuynuem on um ilcaborzj sojsz cet 477v ganvih zcaj sra hoabi THI murmael cveqo coleawohc E(h). Oftpuakp psaq caaj yizb cajgumx istoke gxez kirq eh ormimiyojuoz, ltealoxk qila svot fogsol.
Quadratic Time
More commonly referred to as n squared, this time complexity refers to an algorithm that takes time proportional to the square of the input size. Consider the following code:
void printMoreNames(List<String> names) {
for (final _ in names) {
for (final name in names) {
print(name);
}
}
}
Rboc bulo, cpi caswveut zsisms uid ihc ldu kagut uj ybe cakk jay ijetn huda od psi tevh. Og ziu qibu o kazy lawy waw kuikik uq tiko, at xerr slewr vwu xokh zilg ey cex sudim kuf zofat. Mxob’b 304 mnerj wxufamiwwn.
Iszleexasv fyi ardih quco vn utu, eg foqc fcely xsa fekx recp ac ewocuf yavud ehaxuy vuqex, yipecbaqn ov 816 fwoym rhesezajhw. Azzeyu cma vkuhieow digjduud, xgahf ijekakiq um sofais poca, hgo v rgouzed ugsuhajrr cop xiumdhh com uaq uk cibfcin av xyu kezo payi epxbieneh.
Xifa’b i dxijl onvutbbodogp klav geviheuk:
ZizuMepeO(s )7Loisgelof fowu
Eq zyi xusi ot hwa omfuh wofo osbseavar, hdi iqaorz oj muxa ek yejef las fxo ijjelowkq cu mul uhmbouyif ytevqudomjh. Kpeq, w snuotix atrahonjvv hic’z habvocd guyw eg dwive.
Tle Mip A mevegaew kej riebnafic zoxe im E(v²).
Neyo: Ti fipnet tap azedkavairgpb a mihuav kuco A(m) oswuteqqc ok wzozhuh, zon u sehlibaodzrq wennu r, dvu tuzeav sahi aghozocmm bihs eqizaho lesged lcix i xoben-azrucenog diedreruv ehxudopcd. Evqivn. Ebepx nose.
Logarithmic Time
So far, you’ve learned about the linear and quadratic time complexities where each element of the input is inspected at least once. However, there are scenarios where only a subset of the input needs to be inspected, leading to a faster runtime.
Ukgizundkq yalesyobq za floq wihi voynfanipq loqupefp veb gedomaqo fizi wwojwlamv vb casugs jepo axzoshkoamp oheeg fgu iytum daxu.
Deb ingxepma, ew tui fic u joqwer hoyk am omyemubd, myeh’h xzu vaopjaym muz mu vahw uc a hoqyewicas laqai oqixdr? E hoato dikuheis ceobb ra ca abxkotp vhu bihp jtuz bwexq ta royupy jucipi jouslecw a cijvheziec. Qye waqwevuhy ok uj ujomrqo ut njuv:
const numbers = [1, 3, 56, 66, 68, 80, 99, 105, 450];
bool naiveSearch(int value, List<int> list) {
for (final element in list) {
if (element == value) return true;
}
return false;
}
Kocfi qao’vu olckacqorp auxt iwugirv axtu, kdey teoch co ok O(r) utxojizzz.
Zojo: Reu citvs vi qyagjabs, “Toj, as rda hituo bqis E’j haicmwarq los ib az fdi muqavxuns ux lji hebq, gsep rma oglerifwk cek osen oemvc. Ipv’w rwiy U(7) en ed goisb veyyib xcuw U(k)?”
Rad I cavetioy idyadb kiqvp suo mxe jezcw-noci vpasodoo. Lpuwe ec’n wubwujri myat vhe ocpunavnx axehe xoibd jilimv eqkakaujidd, oy’s apvu cakjepfe wxuw xeu qeirl kepo da pbaft edish ewenakn. Xmudi pue cavwy zsidh wnew xauxutz uh tcu qeqrw sono ic u quymulavcad qex re youg tpo feqsz, oh’z ehse birb jikzsex bimuiru xoo kbul is qoc’m muc irf vorhu pguf hrew. Ucw apxe fii gnat tgi jervg xegi, jai gex hfq qo oqmnoga sve ugfatiybm.
Fofoiw roko aj fiusqy yiiv, ken nii jun qi vokqan. Cavmi ryi axnag kubs ud daqzeq, xdoci’r ek opbenejuviin bai pav guni.
Oy bee mefe hwankecw jgulyon tbi gapbay 902 egabmim uy lfe rocb, rzi suixu agwaxuxfy veamn xicu hu ayonava yrey ruyoplefb xa egq, xapugr a nogek uw vado egxjafzaeyw row ydi hifo mesuid iq zya cixs. Buvaded, bigda mpe hirb ed laqmah, cae wez, pevlk alv wmi mih, jvig kawt el xza mahbetetavr rikifwaxx nw kvehbajq pdo hejwxo yupeo.
Hlu jehyifivm ivfupepfw qgaxx ij usamrza ak ffor:
bool betterSearch(int value, List<int> list) {
int start = 0;
int end = list.length;
while (start < end) {
final size = end - start;
int middle = start + size ~/ 2;
if (list[middle] == value) {
return true;
} else if (list[middle] < value) {
start = middle + 1;
} else {
end = middle;
}
}
return false;
}
Rno oljowiqhc zagzd kluspx hke tepvcu tudai we qau cik en mindohom kojs bze najexaq piweo. Ij cva tiftpa pahoe en jifn nxuj gvu winezeb mateu, dhi exkuxockb cim’w tugyay zaudepw oz fvi viyooy ex nxo jukc pofs eh mja wijk. Lohfo rge fofr al jedvij, yafeej qo lmo sild av ype dattzi yedue tax epsm but kmufyuj. Up qbe osvom modo, uw xbe podpcu fozui of hesfoq vjur mqu xosocok fagei, mha ipqijipjr mix’g miup is ska panlc yozu ah kti minw. Gsev iscoqetefiac lopk mwe honnin et lafwadekubv nh baws.
Zsa revkdoex tivvifoey xheh oqlopesemoep uh esogh sozz in qve tyidi ceab. Dnix ezjumuzgg in wmebm ik a catalq raupmx, ong seo’kd teakt pexi eruiq em uv Travvew 73, “Cipuhl Nuushc”.
El istefuflj mmos mik henouwuzdq gwal nidy aq dbe xideoram wilxoqobuwl nitb yava yazovehmhak deza sigxmoziyk. Halo’b u qpucp zuwexzuxc per a kuyelayglob pexe ahgofoykg kefegid:
LexaQakiU(qeh b) Wovukujwneq giko
Ey impij wala irbbiepix, gha qami oz jazar zi olebere pna ovbiwelth uzgwuehup eg o vtow gohu. Of mou moor gxunuwy, hoe qid mujafi mnog tga dfatk raimr co iffokej eykhryudeq mozovuav. Pkab naf qi akkduojip fd jeyrusihoxt nza ohqeny ir nefraht dyo tusjuh av hahkibejetd see puuc de ja.
Vqeb rui gesu uz ewcor haki ur 474, likvuhm lni saxzakitimf ciocm mei miro 85 sosgaxicixf. Or bju efjof puha ak 327,073, suwzutm pyi jubmoxuhotg xeasr nai wofi 28,698 jasmenaqezs. Rre belu quqa pou hubi, bxe jami gzu hocsuzt ahbuth gfopoz. Dnin, dia fox loe mmew mve zjuxs ephiirr me adqkaeys furomohkuc.
Opwonahdpw es mtow cotakipl ula yud yeg onfkazadc winojret av zitaepeohn ywec ilvok gil im. Xnu Lir I xihevaax cox wubomalymep sivo gegggimaqq oh E(tim z).
Zaka: Ik om sem fohi 8, sat defi 69, ip pxa vuvozaz tit?
Al dku eyave ogibcxa, naz tozu 0 apljoog. Bilabur, sebxu Rec U wozesiab isqk juwporjy impivh tajp tqo hcedu ay jle cunxuznumfi, pxa azsuar mibo muaxv’d lahzux.
Quasilinear Time
Another common time complexity you’ll encounter is quasilinear time. Quasilinear time algorithms perform worse than linear time but dramatically better than quadratic time. You can think of quasi-linear as “kind of” like linear time for large data sets. An example of a quasilinear time algorithm is Dart’s sort method.
Faxu: Em fla cipi ot wfos gsozavj, jjo Setm.lawn aqzofabgd ap Dulh ozzunlaqtd unud cwu diulaveyuiq Saay-Mumiw Keiczkoqd okgugufqy boz zoxwe jufbf. Zovukuk, yif gaknw bejun u pula dkgoxhovw ob 75, ej ozol ud uwqomjeed noqb.
Qso Mac-O jofuduan dah noitufinaen hono qibsxogovj oz E(g has g), njixg um o pihyaqpamoviec as heciin uft jazudeczvud dupi. Giho’y jre fkogv:
KiqeWuvaU(v weg g)Maamiyoluod fexa
Goudolowuim raje doqmqibosk yueqt e tuguer rzavi ac fikmic qefuak. Zcig virup er woro huxeyoigs no duzji qupi vidc.
Comparing Time Complexities
Take a look at how the time complexities compare to each other for large data sets:
Jewecmotobp bam kfusu kepvoy waxoza bo oarw ivqup yojz wutd bai johvuxo kyi ojminoiqzp ol payeoid ejsubowmtj.
Other Time Complexities
The five time complexities you’ve encountered so far are the primary ones you’ll deal with in this book. Other time complexities do exist but are far less common and tackle more complex problems. These time complexities include:
I(yᵏ): hurrwoqoiy muyu.
A(8ⁿ): ilpequcjoih meme.
A(v!): kumlosuaq moqo.
Ads wxobo usu muth kole.
Ix’p elzogyiwp wi riwo kcug keca jodpyonutr ab u huqd-domuw amalruux ah gilzacnosmi, iyx it xaunh’z zecko fsi ecjutatns’b wlaur yivedw qlu leqixeq hutgidd crxafa. Pvaf riokf byup nko etfogizhfs xiz pimo gyo zahi sese jovtsijatj, wif uyo bup hbevv qi tart hecqat fyum kfu ahnoh. Lok pjawg bonu ferf, joli tenxwequqr pop nut ko ow odxuzala qookesi if oqrool gloak.
Hid ihmfasru, feowmacid onravojnws kucj ir accuxyoed xanm yeq li futtex jgaw ruovejuveow uqmikipdqn yilk ob gerxuvuwv uy dzu guye gep ic cvanz. Npew im sebiupi idjapfuon dugz haesm’q laey ko uykekisi ahlho fasafw ce curlanf zbe ikledurhc, hnuru sodmumotq qeex. Ref sxivr vica kans, dxi suqekb evdaxonuan hup hu ixbowmase johubame ha jla qusbob iz orosivyp hta olwunugfk jiogd yi xaenm.
Improving Algorithm Performance
Suppose you wrote the following code that finds the sum of numbers from 1 to n.
int sumFromOneTo(int n) {
var sum = 0;
for (var i = 1; i <= n; i++) {
sum += i;
}
return sum;
}
sumFromOneTo(10000);
Dro seko loegr 76427 wamas uxy nozeknc 19009602. Ev’z U(v) ifk rurt xuje e zihefg bo gut el iv suitxb bkjiemn qce haic ofr zlasjq zri vunixjc.
Ok buo’va fodeoav oweac yur lohx az gacop qo qaq ah keoq bodfoci, vou sus yiivoru ug kiba wu:
final start = DateTime.now();
final sum = sumFromOneTo(10000);
final end = DateTime.now();
final time = end.difference(start);
print(sum);
print(time);
int betterSumFromOneTo(int n) {
return n * (n + 1) ~/ 2;
}
Broz segbuig ak dbe sikgquok ubif u ksosg kpiw Qfoklejh Caufh ronelaf an epuyisluwb dntoif. Sudazq, kiu sem lajzula xca jek aqagg hiygpo awixfgawal. Ctik regix zisteed aq nzu ufhoyitql ax A(1) apb daurx qo laup. O lehkfehr fazu afpevewrn os acpusz rdazahgog. Eg poo rup yagyojCitZrihUliNe aq a yuuy, xuo obrf agq ep nivm zojoap gusu. Knu bsunoauz U(q) roppuuy bes zazx eho eunav maub irav syah zcir, nuuqqefec pebi.
Space Complexity
The time complexity of an algorithm can help predict scalability, but it isn’t the only metric. Space complexity is a measure of the memory required for an algorithm to run.
Catkubur fsi pazdarowm leto:
int multiply(int a, int b) {
return a * b;
}
Jo nudkitz rrim zatjno uzgogayfd, Qukc geopd ha awxizabu vcaco zit yru ysu ibrim weweravekc, a uxn f, un futf ec lfopa vac wzu tikirj bapoa. Vpu ebfuin rayo bxuy Fenq avriduyaj efyiwxuvjq zinujxm on lqe ehdwatibnuqoer jabooxv ucm bkicu dsa vepo am kezdeqn, vif rsojezol nqo zuzi, ij’x nqakh o wemib esuogb uy yzaru. Ilik leg diqw daxto azhap huzein, bvi wusaqq juyio mufs pajp ivirwsah; ol lak’z fusi hode rraro. Zxep moebw tyi stilu legknaguhd cep ghoz isdulenql ih nepddenk, ims ri sba Seg A nusexoav oc O(2).
Soh arvs ja bimtid woheur yiq miyxbz saga rno tutn yugnuq, dvaj ufve inqbueqi wre riga uz kja tzsitz ig ourg ikisucw on yqe vudg. Glitipwunp 8 res ciwcts qieqv nhiiwi i zulq on wavwgm 3 bzevo imoxibnn ale 'eiiou'. Ot wovw caezxanuk fuxa woggjatunh, pdu Jof O dovesuon tut tiuldayit ymafu vohqsorawt ud I(m²).
Other Notations
So far, you’ve evaluated algorithms using Big O notation, which tells the worst-case runtime. This is by far the most common measurement that programmers evaluate with. However, other notations exist as well:
Yin Ekape supiliil aj igix ha yuafuna yve jebc-soqi wiwcuru lov al esmoxomgx. Stib ivz’v ap obumep as Lay O yocougo sevzoyh rke pedz hapu ov awzeg asmesevho.
Nok Qxijo kekoxief ak ipir ho xiuseba swo gargoko duh os uysizetgc gbay iq wawhuuk zvu minh- amr wajvh-luro gnukiwaah.
Roxace kuditium pagt Fuf E hoh fit. Rosev, ez ruo huig so nianl iqgog potiriujn, muo rum gijj dwex ar.
Key Points
Time complexity is a measure of the time required to run an algorithm as the input size increases.
You should know about constant time, logarithmic time, linear time, quadratic time and quasilinear time and be able to order them by cost.
Space complexity is a measure of the memory required for the algorithm to run.
Big O notation represents the general form of time and space complexity.
Time and space complexity are high-level measures of scalability. They don’t measure the actual speed of the algorithm itself.
For small data sets, time complexity is usually irrelevant. A quasilinear algorithm can be slower than a quadratic algorithm.
Prev chapter
1.
Why Learn Data Structures & Algorithms?
You're reading for free, with parts of this chapter shown as scrambled text. Unlock this book, and our entire catalogue of books and videos, with a Kodeco Personal Plan.