Óvakodj az enumtól, mert lassú lészen az – áll a .NET bibliában.
Ártatlan kis jószágnak néz ki ez az enum, mégis sokszor láttam már, hogy miatta lassul be egy rendszer. Mi a lassú rajta? Minden. A Parsolás pl. De ez még érthető is. De hogy a ToString() is tetű, az már kevésbé. Sajnos azonban reflectiont használ ezekhez a műveletekhez, ami köztudottan lassú.
Szerencsére elég könnyű segíteni a baján. Ha Parsolni kell, azaz egy string alapján kell egy enum értéket megszülni, akkor ezt egyszerűen meg lehet oldani egy Dictionary-vel, ami string kulcsokkal és az konkrét enum értékekkel van feltöltve.
Most a másik oldalt mutatom meg, a turbó ToString()-et.
Egyszerű demó enumunk:
public enum TradeDirection
{
Short,
Long
}
Ebből tehát ha van egy példányunk amin ToString()-et hívunk, az lassú lesz. Hozzunk létre egy Dictionary-t, ami segít az enum-string asszociációban.
private static Dictionary
Ezt kellene felölteni értékekkel. A C# generikus dolgaival szépen meg lehet ezt általánosan is fogalmazni, így mindenféle enumra működni fog:
tradeDirectionNames.FillEnumCache();
public static void FillEnumCache
{
foreach (T enumValue in Enum.GetValues(typeof(T)))
{
enumNames.Add(enumValue, enumValue.ToString());
}
}
Mivel extension methodként írtam meg olyan, mintha a Dictionary tudná ezt a funkciót, a T típusparamétert meg kitalálja a compiler, így nem kell kiírjam a teljes alakot:
tradeDirectionNames
Hogy jogos-e erre az extension method az objektumorientált szempontból erősen vitatható, de nekem így kézre esett.
A generizálhatóság viszont szenzációs. Ezért imádom a C#-ot.
Miután a fenti megoldással gyorsítottam a rendszeren kiderült (profilerrel, mi mással), hogy egy összetett típusban ami két enumból állt lassú volt a GetHashCode implementációm, ami így nézett ki:
public override int GetHashCode()
{
return dir.GetHashCode() + zone.GetHashCode();
}
A dir és a zone egy-egy enum.
A gyorsításhoz így írtam át:
public override int GetHashCode()
{
return (int)dir << 4 + (int)zone;
}
[/source]
Ez nem csak gyorsabb, de jobban is szór, mint az előző.
Could you hire me? Contact me if you like what I’ve done in this article and think I can create value for your company with my skills.
LEAVE A COMMENT
7 COMMENTS
Nekem azért furcsa ez, mert nekem pont ez tetszett annó a .NET-ben a Java-hoz képest, hogy rengeteg enum-ot használ!
Ennek hatására kezdtem el én is erőteljesen használni Java-ban az enum-okat.
Ezek után ha akad egy kis időm, majd én is ránézek profilerrel.
Kíváncsi vagyok mit látsz. Nekem ez már nem az első eset, hogy belefutok.
Hello,
Ennek az éremnek is két, de lehet hogy több, oldala van.
Hányszor hallottam hogy fúúúúj string + string… helyette string.format, meg stringbuilder…
Persze… igaz ha 1 millioszor kell ciklusban napi 100x ezt csinálni, vagy életek múlnak rajta…
De ha nem akkor nem kell bit szintre lemenni…
Ez a c# és a fejlett nyelvek lényege!!! Absztrakció… A problémával foglalkozunk, és nem a tényleges technikai megvalósítással.
Tehát nem kell most rohanni és minden enum-t azonnal átírni, és a következő projektekben elő sem venni.
Fel kell mérni, a helyzetet, és a szerint dolgozni. Mert lássuk be: az enumok megkönnyítik az életet : egyszerűsítenek, átláthatóbbá teszik a kódot, érthetőbbek, beszédesek…
Ettől persze igaza van Socinak a fenti példában.
De ilyet találunk minden mérnöki területen: követelmény-kényszer ill. fizikai/technikai ellentmondások területen…
Kicsi legyen a telefonom bírja sokáig az aksi (nagyobb kell)
Ez a szép… át kell hidalni :)
Üdv,
KRis
Persze, ettől még nem dobtam ki én se az enumot, csak körbeprogramoztam ott, ahol lassú volt.
Már majdnem azt hittem, hogy egy fricskát elengedhetek, hogy minek leprogramozni azt, amit a MS már megcsinált egyszer… ;-)
De aztán rácsodálkoztam, hogy a System.ComponentModel.EnumConverter nem chache-el… :-( Pedig mindene megvan hozzá…
Természetesen: chache=cache vagy magyarosan: kessel