|
ZaΦßteΦnφk |
PokroΦil² |
Profesionßl |
|||||
|
|
|
||||||
Optimalizace
/3. dφl Cφl: RychlejÜφ a efektivn∞jÜφ programov² k≤d |
||||||||
|
|
Budete pot°ebovat
p°ibli₧n∞ 70 minut |
|
OperaΦnφ systΘm
pou₧it² v p°φsp∞vku: Windows 2000 V²vojovΘ nßstroje:
Visual Basic 6.0 SP5 |
||||
|
Milφ Φtenß°i,
dneÜnφm dφlem zakonΦφme problematiku optimalizace zdrojovΘho k≤du ve Visual Basicu 6. V p°edeÜl²ch Φßstech jste se dov∞d∞li, jakΘ mo₧nosti optimalizaΦnφch nastavenφ vßm VB 6 nabφzφ a rovn∞₧ tak vφte, jak zm∞°it rychlost provßd∞nφ jistΘho ·seku programovΘho k≤du. T°etφ a zßv∞reΦnφ Φßst bude v∞novßna praktick²m ukßzkßm optimalizace k≤du. Budeme zkoumat, jak² dopad na v²kon k≤du budou mφt nßmi pou₧itΘ techniky optimalizace.
Obsah |
M∞°enφ tempa programovΘho
k≤du p°i pou₧itφ prom∞nn²ch r∙zn²ch datov²ch typ∙ |
Experiment
Φ. 2: KritickΘ omezenφ rychlosti prßce ovlßdacφch prvk∙ |
Experiment Φ. 1: Zßhady pou₧itφ datov²ch typ∙
Pokud mßme mluvit o komplexnφ optimalizaci programovΘho k≤du, musφme vychßzet ze zßkladnφ programovacφ entity, kterou je prom∞nnß. Kdyby existoval jenom jeden datov² typ, kter² by byl pou₧iteln² na vÜechny programovacφ operace, bylo by mo₧nΘ do n∞j ulo₧it tak°ka cokoliv a jeho pou₧itφ by nijak neovlivnilo rychlost provßd∞nφ programov²ch instrukcφ, nebyla by otßzka pou₧itφ vhodn²ch datov²ch typ∙ prom∞nn²ch ani zdaleka tak d∙le₧itß. I kdy₧ je p°edstava ideßlnφho datovΘho typu jakkoliv lßkavß, p°i praktick²ch pokusech zßhy zjistφme, ₧e o n∞jakΘm äideßlnφmô stavu si m∙₧eme nechat jenom zdßt.
Visual Basic 6 poskytuje znaΦnΘ mno₧stvφ rozliΦn²ch datov²ch typ∙, kterΘ dovedou uchovßvat r∙znΘ hodnoty. ProblΘmem pochopiteln∞ nenφ deklarace prom∞nnΘ k²₧enΘho datovΘho typu. Kdepak. Daleko slo₧it∞jÜφ je vypracovßnφ si jistΘ intuice, kterß vßm bude °φkat, jak² nejvhodn∞jÜφ datov² typ byste m∞li zvolit v zßvislosti od °eÜenΘho problΘmu. Bohu₧el otßzka optimßlnφ volby datovΘho typu pro danou operaci je n∞kdy natolik slo₧itß, ₧e ani pokroΦilφ programßto°i Φasto nev∞dφ, zdali ta jejich volba byla opravdu optimßlnφ.
Prvnφ dobrß rada znφ: V ka₧dΘm p°φpad∞ deklarujte prom∞nnΘ pomocφ klφΦovΘho slova As a specifikace vhodnΘho datovΘho typu. Visual Basic sice umo₧≥uje deklaraci prom∞nn²ch bez udßnφ platnΘho datovΘho typu, ovÜem v tomto p°φpad∞ vφce ztratφte, ne₧li zφskßte. Jestli₧e p°i deklaraci prom∞nnΘ nebudete specifikovat jejφ datov² typ, bude ji automaticky p°i°azen datov² typ Variant. Typ Variant je jedin² typ, kter² m∙₧e uchovßvat hodnoty jin²ch datov²ch typ∙. Na druhΘ stran∞ je to takΘ ä₧rout pam∞tiô, proto₧e ka₧dß instance prom∞nnΘ tohoto datovΘho typu zabere 128 bit∙ (16 bajt∙) pam∞ti.
GenerickΘ prom∞nnΘ, co₧ je nßzev pro prom∞nnΘ, kterΘ nemajφ explicitn∞ determinovßn specifick² datov² typ, jsou ovÜem v mnoha p°φpadech u₧iteΦnΘ (nap°φklad, kdy₧ budete chtφt vytvo°it instanci jistΘ t°φdy za b∞hu programu, no v dob∞ psanφ k≤du nebudete znßt specifick² typ t°φdy, pou₧itφ generickΘ prom∞nnΘ m∙₧e vy°eÜit vßÜ programßtorsk² problΘm). Naopak, v₧dy, kdy₧ je to mo₧nΘ, m∞li byste explicitn∞ urΦit specifick² typ prom∞nnΘ. Budete-li chtφt spustit instanci aplikace Microsoft Word a p°idat do nφ jeden dokument, budete deklarovat objektovou prom∞nnou pomocφ specifickΘho typu t°φdy Word.Application:
Dim
Objektovß_Prom∞nnß As Word.Application
Set
Objektovß_Prom∞nnß = New Word.Application
With
Objektovß_Prom∞nnß
ááá .Documents.Add
ááá .Visible = True
End With
Pou₧itφ specifickΘho typu objektovΘ prom∞nnΘ v uvedenΘm p°φklad∞ demonstruje takΘ mechanizmus, jemu₧ se °φkß early-binding, neboli ΦasnΘ vßzßnφ (vznikl²m instancφm t°φdy se pak °φkß objekty s Φasnou vazbou). Pou₧itφ ΦasnΘho vßzßnφ je velmi u₧iteΦnΘ takΘ pro vßs, jako programßtory. Ve chvφli, kdy uvedete specifick² typ objektovΘ prom∞nnΘ, bude Visual Basic v∞d∞t, jakΘ metody a vlastnosti danß t°φda obsahuje a tyto vßm zp°φstupnφ prost°ednictvφm technologie IntelliSense p°i pou₧itφ teΦkovΘho operßtoru.
|
Aby uveden² fragment programovΘho k≤du pracoval spolehliv∞, musφte do
vaÜφ aplikace zavΘst odkaz na objektovΘ knihovny: Microsoft Office 10.0 Object Library a Microsoft Word 10.0 Object Library.
V IDE Visual Basicu vyberte nabφdku Project a klepn∞te na polo₧ku References. V seznamu pak vyhledejte uvedenΘ knihovny a
zahr≥te je do projektu.á Poznßmka: ObjektovΘ
knihovny verze 10.0 p°inßle₧φ softwaru Microsoft Office XP (2002). Pokud mßte
na svΘm poΦφtaΦi nainstalovanou jinou verzi, pou₧ijte samoz°ejm∞ tu vaÜφ.áá |
V nßsledujφcφ sekci se podφvßme na to, jak² vliv na v²kon provßd∞nφ programovΘho cyklu bude mφt zvolen² datov² typ p°edm∞tn²ch prom∞nn²ch.
M∞°enφ tempa programovΘho k≤du p°i pou₧itφ
prom∞nn²ch r∙zn²ch datov²ch typ∙
Nynφ si p°edstavφme obsahy dvou udßlostnφch procedur dvou tlaΦφtek. V obou p°φpadech budeme provßd∞t matematickΘ v²poΦty, ovÜem poka₧dΘ s jinou sadou datov²ch typ∙ prom∞nn²ch. V udßlostnφ procedu°e Click prvnφho tlaΦφtka budou deklarovßny prom∞nnΘ datovΘho typu Long:
Dim
lng╚φtaΦ As Long, x1 As
Long, x2 As Long
Dim zaΦßtek
As Single
zaΦßtek = Timer()
For
lng╚φtaΦ = 1 To 200000
Randomize
x1 = Rnd() * 10000 + Rnd() * 500
x2 = x1 ^ 2
Next
lng╚φtaΦ
MsgBox "Cyklus s prom∞nn²mi typu Long byl vykonßn za "
& _
Format(Timer - zaΦßtek, "0.000")
V udßlostnφ procedu°e Click druhΘho tlaΦφtka budou zase pou₧ity prom∞nnΘ datovΘho typu Variant:
Dim
var╚φtaΦ As Variant, x1 As Variant, x2 As Variant
Dim
zaΦßtek As Single
zaΦßtek = Timer()
For
var╚φtaΦ = 1 To 200000
Randomize
x1 = Rnd() * 10000 + Rnd() * 500
x2 = x1 ^ 2
Next
var╚φtaΦ
MsgBox "Cyklus s prom∞nn²mi typu Variant byl vykonßn za
" & _
Format(Timer - zaΦßtek, "0.000")
Jednotlivß m∞°enφ jsou uvedena v tab. 1.
Tab. 1 |
|
|
╚φslo
m∞°enφ |
Prom∞nnΘ
datovΘho typu Long |
Prom∞nnΘ
datovΘho typu Variant |
1. |
0, 418 s |
0, 484 s |
2. |
0, 418 s |
0, 480 s |
3. |
0, 422 s |
0, 520 s |
Pr∙m∞r |
0,
419 s |
0,
495 s |
á
Po provedenφ test∙ m∙₧eme prohlßsit, ₧e k≤d s prom∞nn²mi datovΘho typu Long byl proveden v pr∙m∞ru o p°ibli₧n∞ 76 tisφcin vte°iny rychleji ve srovnßnφ se sv²m ävariantnφmô prot∞jÜkem (obr. 1).
Obr. 1 û P∙sobenφ r∙zn²ch datov²ch typ∙ na rychlost
provßd∞nφ programovΘho k≤du
PokraΦujme aktivacφ pokroΦil²ch optimalizaΦnφch nastavenφ, kterΘ nßm nabφzφ samotn² Visual Basic. Postupujte takto:
Po op∞tovn∞ proveden²ch testech jsem zφskal novΘ ·daje, kterΘ jsou zobrazeny v tab. 2.
Tab. 2 |
M∞°enφ v²konu programovΘho k≤du s pou₧itφm pokroΦil²ch
optimalizaΦnφch nastavenφ |
|
|
╚φslo
m∞°enφ |
Prom∞nnΘ
datovΘho typu Long |
Prom∞nnΘ
datovΘho typu Variant |
|
1. |
0, 391 s |
0, 449 s |
|
2. |
0, 391 s |
0, 449 s |
|
3. |
0, 402 s |
0, 441 s |
|
Pr∙m∞r |
0,
395 s |
0,
446 s |
|
Z tabulky je jasn∞ patrnΘ, ₧e exekuce
programovΘho k≤du obou udßlostnφch procedur byla op∞t rychlejÜφ. áV²kon programovΘho k≤du s prom∞nn²mi
datovΘho typu Long byl lepÜφ v pr∙m∞ru o Φty°iadvacet
tisφcin vte°iny. Zrychlila se rovn∞₧ exekuce programovΘho k≤du
s prom∞nn²mi datovΘho typu Variant, a to v pr∙m∞ru o 49 tisφcin vte°iny. Ze vzßjemnΘho rychlostnφho porovnßnφ
udßlostnφch procedur op∞t vφt∞zφ ta, v t∞le kterΘ jsou deklarovßny
prom∞nnΘ datovΘho typu Long. V²konnostnφ nßskok Φinφ p°ibli₧n∞ 51 tisφcin sekundy (obr. 2).
Obr. 2 û V∞tÜφ rychlost exekuce
k≤du pomocφ aktivace pokroΦil²ch optimalizaΦnφch nastavenφ
Jak je
vid∞t, zapnutφ optimalizaΦnφch voleb zabezpeΦilo jeÜt∞ dalÜφ nav²Üenφ v²konu
programovΘho k≤du. Komplexnφ ukßzku porovnßnφ rychlosti k≤du bez a
s pou₧itφm optimalizaΦnφch nastavenφ m∙₧ete vid∞t na obr. 3.
Obr. 3 û Ukßzka vlivu
optimalizace na rychlost provßd∞nΘho k≤du
Experiment Φ. 2: KritickΘ omezenφ rychlosti prßce ovlßdacφch prvk∙
Pokud pracujete Φasto s mnoha ovlßdacφmi prvky, mo₧nß, ₧e jste ji₧ narazili na problΘm, kterΘmu se v programßtorskΘ hant²rce °φkß äkritickΘ omezenφ rychlostiô. Ka₧d² ovlßdacφ prvek je samostatnou entitou, kterß je zalo₧ena na zßkladnφch principech objektov∞ orientovanΘho programovßnφ. Jednφm z princip∙ je takΘ zapouzd°enφ programovΘho k≤du ovlßdacφho prvku, kter² nenφ v ₧ßdnΘm p°φpad∞ p°φstupn² svΘmu okolφ (klientskΘ aplikaci). Na jednΘ stran∞ je existence zapouzd°enφ jasnou v²hodou pro autora ovlßdacφho prvku, proto₧e ten mß jistotu, ₧e k samotnΘmu jßdru prvku se nikdo äzvenkuô nedostane. Na druhΘ stran∞ ovÜem vyvstßvß otßzka, jak dokonale zvlßdnul autor optimalizaci programovΘho k≤du svΘho ovlßdacφho prvku. Je prßce s ovlßdacφm prvkem flexibilnφ nebo ne? A prßv∞ te∩ se dostßvßme k vysv∞tlenφ ji₧ p°edest°enΘho syndromu kritickΘ omezenφ rychlosti ze strany ovlßdacφho prvku. Jakmile jednou v programovΘm k≤du dovolφte ovlßdacφmu prvku, aby p°evzal chod programu do sv²ch rukou, nemßte ₧ßdnou Üanci na jakoukoliv optimalizaci jeho Φinnosti. Uve∩me si mal² p°φklad:
Dim
x As Integer, Φas As
Single
Φas = Timer()
For
x = 1 To 30000
List1.AddItem x
Next
x
MsgBox "Napln∞nφ seznamu trvalo " & Format(Timer -
Φas, "0.000")
Pov∞zme, ₧e procesor bude pot°ebovat p°ibli₧n∞ jednu sekundu na to, aby do seznamu p°idal 30 tisφc Φφsel. I kdybyste zapnuli vÜechna optimalizaΦnφ nastavenφ, nedosßhli byste ₧ßdnΘho signifikantnφho nßr∙stu rychlosti k≤du. Tento okam₧ik je oznaΦen jako kritickΘ omezenφ rychlosti ze strany ovlßdacφho prvku. Hlavnφm ävinnφkemô je metoda AddItem ovlßdacφho prvku ListBox. Jak jsme si ji₧ pov∞d∞li, kdy₧ p°edßme °φzenφ k≤du do rukou metody AddItem, nem∙₧eme dßle optimalizovat rychlost p°idßvßnφ polo₧ek do seznamu, proto₧e touto kompetencφ disponuje jenom samotn² ovlßdacφ prvek ListBox. á
AΦkoliv nem∙₧eme v tomto p°φpad∞ zabezpeΦit zv²Üenφ absolutnφ (resp. objektivnφ) rychlosti programovΘho k≤du, m∙₧eme b∞hem doby prßce metody AddItem zam∞stnat u₧ivatelovu pozornost a informovat ho o tom, ₧e aplikace prßv∞ dokonΦuje jeden ze sv²ch pracovnφch ·kol∙. Na rozpt²lenφ u₧ivatele se v²born∞ hodφ ovlßdacφ prvek ProgressBar (ukazatel pr∙b∞hu).
Instanci ovlßdacφho prvku p°idßte na formulß° nßsledovn∞:
Zdrojov² k≤d v procedu°e CommandButton1_Click modifikujte podle vzoru, jen₧ je zobrazen nφ₧e:
Dim
x As Integer, Φas As
Single
Φas = Timer()
Form1.MousePointer = vbHourglass
DoEvents
Dim
h As Object
Set
h = ProgressBar1
With
h
ááá .Min = 1
ááá .Max = 30000
End With
For
x = 1 To 30000
ááá List1.AddItem x
ááá h.Value = x
Next
x
h.Value = h.Min
Form1.MousePointer = vbDefault
P°i studiu k≤du si m∙₧ete vÜimnout n∞kolik zajφmav²ch programovacφch prvk∙:
╚as, kter² bude pot°ebn² pro vykreslenφ a aktualizaci ukazatele pr∙b∞hu bude, p°es vÜechny pokusy o optimalizaci zdrojovΘho k≤du, o n∞co delÜφ, ne₧li p∙vodn∞ zjiÜt∞nß hodnota. Vskutku, takΘ ovlßdßnφ ovlßdacφho prvku ProgressBar n∞co stojφ. Pro dosa₧enφ optimßlnφho v²sledku je zapot°ebφ najφt rovnovßhu mezi objektivnφ a subjektivnφ rychlosti aplikace.
|
Jestli₧e chcete, m∙₧ete uvedenou situaci vy°eÜit jeÜt∞ jinak: 1.
Nemusφte pou₧φt ovlßdacφ prvek ProgressBar,
ale jenom zm∞≥te kurzor myÜi na p°es²pacφ hodiny. 2.
Vytvo°te specißlnφ formulß°, kter² zobrazφte u₧ivateli
b∞hem naΦφtßnφ polo₧ek do seznamu (aby byl formulß° °ßdn∞ p°ekreslen, po jeho
zobrazenφ zavolejte funkci DoEvents). Formulß° bude u₧ivateli °φkat,
₧e aplikace prßv∞ provßdφ d∙le₧itou operaci, dokonΦenφ kterΘ si vy₧aduje
dodateΦn² Φas. á 3.
NaΦφtejte polo₧ky do seznamu p°edem, nap°φklad
p°i startu aplikace. 4.
Pokuste se naΦφst polo₧ky v menÜφch
mno₧stvech. Tedy nebudete naΦφtat vÜech 30 tisφc polo₧ek najednou, ale
vytvo°φte menÜφ skupiny polo₧ek (t°eba po p∞ti tisφcφch), kterΘ potΘ naΦtete
rychleji. |
Jßn Hanßk