|
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