Page 1 of 1

Kreslení řetězců - Rychlost ExtTextOut a DrawText

Posted: 27 Apr 2009, 18:58
by zarevak
Dobrý den,
tento příspěvek je inspirován mým nedávným objevem, jak řešit problém s HEX režimem. Porovnával jsem různé metody kreslení a jejich rychlost. Třeba to někomu pomůže ;) Třeba tímto vláknem popostrčím File Comparator, aby byl rychlejší při kreslení v binárním porovnávání 8)

Ve zkratce:
:arrow: Kdykoliv je to možné, místo DrawText používejte ExtTextOut! ExtTextOut je mnohonásobně (8x) rychlejší než DrawText.

Testy:
2000x DrawText(..., DT_NOPREFIX | DT_SINGLELINE) cca 5 sekund
2000x ExtTextOut(...) cca 0,65 sekund

Další funkce na výpis textu:
- TextOut - zjednodušená verze ExtTextOut, Rozdíl v rychlosti minimální - cca 0,65 sekund
- PolyTextOut - jen WinNT, umožňuje více volání ExtTextOut v jednom balíku - jeden balík 2000 řetězců cca 0,60 sekund ;)
- TabbedTextOut - ??? názvem naznačuje základ ExtTextOut, ale s rychlostí DrawText - cca 5 sekund :(
- DrawTextEx - vylepšená verze DrawText - cca 5 sekund

Poznámky:
- Rozdíl v rychlosti TextOut a ExtTextOut jsem při mé nepřesnosti měření nezaznamenal. (Inspirace: KB71230: INFO: ExtTextOut() Instead of TextOut() to Improve Performance)
- Zjišťoval jsem, zda předpočítání lpDX parametru funknce ExtTextOut zrychlí dále výpis. Mám pocit, že výsledek byl opačný - mírné zpomalení, ale které nemohu vzhledem k nepřesností měření podložit.

Měření:
- čas byl měřen pomocí QueryPerformanceCounter() a QueryPerformanceFrequency()
- meření probíhalo s Wide (Unicode) verzemi API funkcí
- řetězec byl 133 znaků dlouhý obsahující znaky pouze z Basic Latin bloku
- kreslení probíhalo přes sebe v jednoduchém cyklu
- první znak se v každém kroku měnil
- nepřesnost/odchylka měření mezi různými pokusy byla cca 10%
- EDIT: Windows XP SP3, ATI Radeon HD 3200 + Catalyst 09.3
- EDIT: Použitý font: Consolas + ClearType Antialiasing

Re: Kreslení řetězců - Rychlost ExtTextOut a DrawText

Posted: 27 Apr 2009, 21:26
by Jan Rysavy
Dva postřehy: měření by chtělo provést na různých operačních systémech, grafických kartách a ovladačích. Setkali jsme se s tím, že tyto faktory hrají zásadní roli.

ExtTextOut() je moc prima v tom, že v jedné operaci podmaže libovolný obdélník barvou pozadí a zároveň vykreslí text. Používáme tuto techniku pro kreslení obsahu panelu. Panel téměř nebliká, přestože nekreslíme do cache bitmapy, ale přímo do obrazovky. Dobře je to vidět při změně velikosti hlavního okna tažením za jeho roh.

Re: Kreslení řetězců - Rychlost ExtTextOut a DrawText

Posted: 27 Apr 2009, 21:52
by zarevak
Doplnil jsem informaci, že se jednalo o Windows XP SP3 s integrovanou grafikou ATI Radeon HD 3200 a Catalyst 09.3 a že byl použit True Type font Consolas s Clear Type vyhlazováním. ;)

Test jsem prováděl spíše pro sebe, ale pak jsem si říkal, že by výsledky mohly zajímat i ostatní. Hlavně mne překvapil ten obrovský výkonostní rozdíl mezi ExtTextOut() a DrawText().

Zkoušel jsem ještě výkon kreslení prázdného obdelníku pomocí ExtTextOut(), FillRect() a PatBlt() - všechny funke byly srovnatelně rychlé (použil jsem systémovou barvu/systémový štětec z GetSysColorBrush()). ExtTextOut má tu výhodu, že není třeba vytvářet štětec a barvu lze nastavit jen pomocí SetBkColor()

Musím říci, že mne funkce ExtTextOut velmi příjemně překvapila - mám základ Directory Line pro DiskMapu hotový, aniž bych musel používat regiony nebo další jiné fígle. ;) Jen mi tam trochu bliká pozadí z WM_ERASEBKGND :(

Až budu mít chvilku, tak třeba provedu měření i na jiných strojích...

Re: Kreslení řetězců - Rychlost ExtTextOut a DrawText

Posted: 27 Apr 2009, 22:07
by Jan Rysavy
zarevak wrote:Jen mi tam trochu bliká pozadí z WM_ERASEBKGND :(
Pro malou plochu jako je directory line bych se neštítil nasadit kreslení do memory DC / cache bitmap.
U větších ploch (panely, viewery) to nepoužíváme, protože na některých konfiguracích bylo přímé kreslení
do obrazovky výrazně rychlejší.

WM_ERASEBKGND jsme v podstatě všude potlačili (nemažeme nic, ale OS tvrdíme, že jsme smazali)
a mazání provádíme až v rámci WM_PAINT. Jinak by plochy blikaly při změně velikosti, což je ošklivé
a rádi to přenecháme konkurenci ;-)

Re: Kreslení řetězců - Rychlost ExtTextOut a DrawText

Posted: 28 Apr 2009, 14:42
by Ether
Jan Rysavy wrote:měření by chtělo provést na různých operačních systémech, grafických kartách a ovladačích. Setkali jsme se s tím, že tyto faktory hrají zásadní roli.
To by chtělo udělat nějakou testovací utilitku a zveřejnit ji tady.

Re: Kreslení řetězců - Rychlost ExtTextOut a DrawText

Posted: 05 May 2009, 08:31
by Jan Patera
zarevak wrote:Dobrý den,
tento příspěvek je inspirován mým nedávným objevem, jak řešit problém s HEX režimem. Porovnával jsem různé metody kreslení a jejich rychlost. Třeba to někomu pomůže ;) Třeba tímto vláknem popostrčím File Comparator, aby byl rychlejší při kreslení v binárním porovnávání 8)

Ve zkratce:
:arrow: Kdykoliv je to možné, místo DrawText používejte ExtTextOut!
Tak konkretne FC v hex rezimu pouziva ExtTextOutA.
Nicmene ExtTextOut neni vsemocny lek:-( Tak, jak je to nyni udelano, s ExtTextOutA nefunguje MBCS a s ExtTextOutW by zase nefungovalo UTF-16 :-(
Co konkretne je pomale? Dokazes to nejak kvantifikovat a kvalifikovat? Rychlost CPU? Jmeno a velikost fontu? Pocet vykreslovanych bajtu?