PowerShell a pole vs. ArrayList vs. HashTable vs. SortedList

Dělám teď nějaké operace citlivé na rychlost přes mnoho objektů a můžu tedy poskytnout nějaký pohled na to, jak je to v PowerShellu s těmito čtyřmy typy "kolekcí". Budu se bavit primárně o chování PowerShell 2.0 protože to je dneska ještě mnohde mainstream a musí s ním všechno fungovat.

Pole

Pole je peklo. Pokud do něho přidáváte položku (například pomocí operátoru += ) tak se vytvoří nové pole, to staré se do něho zkopíruje a přidá se nový prvek. To se změnilo do PowerShell 3.0, kde už je pole kolekce a má i metodu Add() a Clear() .

Ale není to zase až tak strašlivé, protože jako parametr funkce se pole předává odkazem. Tedy pokud se ovšem nemusí konvertovat jeho prvky na jiný typ. To se potom celé zkopíruje a prvky nakonvertují. Příklad by byl například parametr funkce [object[]] a do něho vložené pole typu [string[]] . Tady se nemusí konvertovat, takže jenom odkaz. Naopak kdyby parametr funkce měl typ [string[]] a přitom byste do něho rvali [object[]] , tak by se to muselo zkonvertovat po jednom a tedy zkopírovat.

Samozřejmě, pokud ho vracíte z funkce jako návratovou hodnotu, tak se jeho prvky přeskládají do nového pole typu [object[]] a to bez ohledu na jeho původní typ. Prostě výsledkem funkce je vždy buď [object[]] nebo jeden konkrétní objekt - klasická demence PowerShellu.

Rozhodně nebrat

ArrayList

Je lepší a já ho rád používám. Má ale jednu podstatnou nevýhodu. I tady, pokud ho totiž vracíte z funkce jako návratovou hodnotu, tak ten list PowerShell celý projede kus po kusus a přeskládá všechny prvky do pole [object[]] . Jak u blbých na dvorku.

Můžete tomu pomoci operátorem čárka (něco jako return ,$list) ale to zase potom ten výstup funkce nelze přímo pajpnout do dalšího příkazu - pajpne to tam celý ten list, tedy v podstatě jeden objekt.

HashTable a SortedList

Potřeboval jsem rychle vyhledávat duplicity. K tomu jsem si potřeboval vytvořit index řetězcových hodnot. Vyzkoušel jsem to nejprve na random 200 000 řetězců. A překvapivě!

HashTable je v tomhle dokonce cca 10 krát rychlejší než SortedList jak v případě vkládání klíčovaných hodnot, tak i v případě jejich vybírání (indexer).

Navíc pokud vracíte HashTable jako návratovou hodnotu funkce, tak vám to nekonvertuje její typ a prostě to vrátí ten odkaz.

Tak tohle je miláček. HashTable.

- Ondřej Ševeček, MVP

Mohlo by vás též zajímat:

Advanced PowerShell: Tips and Techniques to Take Your PowerShell Programming to the Next Level