Problém:
Často sa stáva, že niečo ide krásne, keď máme 100 prvkov, ale pri 1000 prvkoch, už je to zabité. Rovnaký problém som mal nedávno pri jednej WPF aplikácii. V zozname aktivít, ktore bolo nutné s 5 sekundovou periodicitou obnovovať bolo nutné zobraziť niekoľko stoviek záznamov.
Dôvod problému:
Pri zmene nejakého prvku v tomto zozname si musí WPF prekresliť (preusporiadať) všetky prvky, čo mu samozrejme trva veľmi dlho a žere CPU. Uložený layout tiež zaberá nejaké to miesto v pamäti.
Riešenie
Našťastie som presne tento problém kedysi riešil v jednej databáze návodov a cheatov (kde sa ich zobrazovalo niekoľko desiatok tisíc). Bola to Win Forms aplikácia. Tam našťastie umožňuje Windows chápať listbox ako virtuálny = kóder rieši iba počet prvkov a aktuálne zobrazené prvky. Ostatné prvky sa ani nezobrazujú, ani nie su v pamäti UI.
Riešenie ala WPF
Veľmi jednoduché – namiesto StackPanel containera použijem VirtualizingStackPanel. Ten sa postará o všetko.
Iné riešenie by bolo napr. nevymazávať prvky, iba ich zamienať a iba v prípade zmeny počtu ich pridávať alebo uberať – ak sa však tento počet mení často, tak sme si veľmi nepomohli + niektorých problémov sme sa stále nezbavili – aj tak ide o relatívne účinný spôsob
Nejaký benchmark
| zoznam v “idle” stave | CPU |
| bez optimalizacie | 40% |
| s optimalizaciou cez “prepisovanie” prvkov | 20% |
| VirtualizingStackPanel | 10% |
Takže zhruba 4-násobné urýchlenie pri cca 1000 položkách – čo je ale dôležité, že tento čas uz bude zhruba konštantný pri akomkoľvek počte prvkov. Aj keď neplatí to tak celkom. Stále hovoríme o “idle” stave. Ak začnem scrollovať v listboxe, tak CPU utešene rastie. Potom mi nezostane nič iné, ako poobzerať sa po iných urýchleniach, ale o tom niekedy nabudúce.
Záver
Odporúčam použivať pri všetkých relatívne dlhších zoznamoch vo WPF. Veľa muziky zadarmo.