• StringId - Effektivt hanterande av strängar som ID:n

    Ibland är det praktiskt att kunna identifiera saker genom namn, istället för genom siffror eller enums.

    Problemet är bara att om man inte passar sig, då kan det ta mycket minne och MASSOR med CPU-kraft, att göra alla stricmp. För några år sen, då jag plockades över på Tycoon City projektet, för att snabba upp spelet (som formligen KRÖP fram vid det laget), visade det sig att dom använde ca 400MB för att lagra strängar (varav de flesta användes just som IDn, och var dubletter i många led), och att strängkopiering och strängjämförelser låg högst upp när man körde spelet genom en profiler. Hur jag löste det då låter jag vara osagt (fick bli som det blev så sent i projektet som det var, men rejält snabbare blev det iallafall).

    Men sedan dess är jag alltid lite på min vakt mot att använda strängar - det kan lätt skena iväg, och det är onödigt att slösa bort både minne och processortid på en sån sak om man inte behöver. Så jag tänkte jag skulle dela med mig av mitt eget system för att lösa den problematiken, utplockad från min Pixie-motor. Det är en stabil och snabb lösning, som är enkel att bara droppa in i vilket projekt som helst, och består av två klasser.

    Grunden är en klass som jag kallar StringId, och som man enkelt skapar genom t.ex.

    Kod:
    StringId mittId("mittNamnHär");
    Internt resulterar ovanstående i att strängen "mittNamnHär" letas upp i en global stränglista (ej case-sensitive), och läggs till om den inte finns där redan. Uppletandet sker via en rätt snabb hash-tabell lookup. I själva StringId-klassen lagras en pekare till den delade strängen, så man sedan kan göra:

    Kod:
    if (enStringIdVariabel==enAnnanStringVariabel);
    och att det bara resulterar, internt, i en jämförelse av två pekare. Snabbt och bra. Tar mindre plats också, eftersom själva strängen bara lagras en gång.

    Dessutom så finns det ett par macros definierade (ibland e dom rätt bra att ha), strSwitch och strCase, som gör att man kan göra StringId jämförelser på liknande sätt som med switch-case statements:

    Kod:
            strSwitch (myFruitTypeStringId)
                {
                strCase(Apples)
                    {
                    // code to do stuff here
                    }
     
                strCase(Oranges)
                    {
                    // code to do other stuff here
                    }
                }
    Motsvarar att man skulle göra nedanstående, men ser lite snyggare ut. Fast det är ju en smaksak förstås :-)

    Kod:
            static StringId applesId("Apples");
            if (myFruitTypeStringId==applesId)
                {
                // code to do stuff here
                }
     
            static StringId orangesId("Oranges");
            if (myFruitTypeStringId==orangesId)
                {
                // code to do other stuff here
                }
    Koden är välskriven och hyfsat välkommenterad och finns att ladda ner här, och är för C++. Som vanligt är det public domain som gäller - använd hur du vill
    This article was originally published in forum thread: StringId - Effektivt hanterande av strängar som ID:n started by Mattias Gustavsson View original post