1. This site uses cookies. By continuing to use this site, you are agreeing to our use of cookies. Learn More.
  2. We need your help nominating resources for or next YouTube video. Post here now.
    Dismiss Notice
  3. Cast your vote for the best created hero from the Hive Workshop! [POLL] +100 REP Team Contest - Hive Member
    Dismiss Notice
  4. The Terraining Mini Contest Reload #1 - Mist has began! Create a scene laden in thick fog, with only 20 doodads!
    Dismiss Notice
  5. Full steam ahead! Choose the best steampunk song at our Music Contest #9 - Poll
    Dismiss Notice
  6. Join us in our custom games night next Saturday, January 27th. We'll see you on Battle.net and Discord!
    Dismiss Notice

[Benchmarks] The truth is (out) there.

Discussion in 'Triggers & Scripts' started by Troll-Brain, Aug 17, 2011.

  1. Troll-Brain

    Troll-Brain

    Joined:
    Apr 27, 2008
    Messages:
    2,372
    Resources:
    1
    JASS:
    1
    Resources:
    1
    I was bored of statements on the fly without any benchmarks provided, and because jass is enough fun for making false assumptions which beat the logic, i decided to make benchmarks.

    I use cJass, just because it's the best tool i know for making benchmarks.
    You can get it there : http://cjass.xgm.ru/

    Because variable and function name length really do matter i will just assume that the code will be correctly optimized (one letter for locals, and two for globals/functions).

    1 for locals because 52 combinations is more than enough (a-Z), and two for globals/functions because it seems also fair (52*62 = 3224) , (62 -> a-Z ; 0-9 but not _ )

    Also don't take me wrong, i'm not a speed-freak, i'm perfectly aware that most of times script optimization is not needed and even that some (many ?) benchmarks here are quite or more pointless in real cases.

    Fps drop test could give different results depending the operating system and the hardware configuration, but i will presume that it is reliable, it's not like we have decent other ways.
    But you're welcome to test these codes by yourself and give your results.
    Or submit your own tests, but plz give the code and the results together, just giving the result is bullshit.

    Oh and btw the title could be pretentious but it's really not, it's just a (bad) pun (X-Files)

    So first, here is a cJass template for benchmarks :

    benchmark template
    Code (vJASS):
    library Benchmark initializer init

        #define private TEST_TO_DO = 1
        #define private PERIOD = 0.01
        #define private CHECK_LIMITOP = true
       
    /*

    TEST_TO_DO -> Attribute unique integers for your tests, then the user has just to edit its value,
    to compare your test codes.

    PERIOD -> it's the timout of the timer, depends mostly your hardware configuration.
    If it lags to much try an higher value, if there isn't enough fps drop, try a lower one.
    Just be aware that the min timeout possible for a timer is 0.0001

    CHECK_LIMITOP -> Set it to true if you want to ensure that your script doesn't reach the limitop.
    When you have checked all your codes (by editing the value of TEST_TO_DO and compiling/running the map),
    set it to false to perform the benchmarks.

    */


        globals
            // put your globals here
        endglobals
       
        #if (CHECK_LIMITOP)
            private boolean limit_op_reached = true
        #endif
               
        nothing T() { // Test function
       
            #if  (TEST_TO_DO == 1)
               
               // put your code here
               
            #elseif  (TEST_TO_DO == 2)
           
                // put your code here
               
            #else
                PauseTimer(GetExpiredTimer()) ; DisplayTimedTextFromPlayer(GetLocalPlayer(),0,0,666,"invalid TEST_TO_DO value, define it with a valid one")
            #endif
           
            #if (CHECK_LIMITOP)
                limit_op_reached = false
            #endif
           
        }
       
        private nothing init() {
       
            #if (CHECK_LIMITOP)
                TimerStart(CreateTimer(),0,false,function T) ; TriggerSleepAction(0)
                if (limit_op_reached)
                    DisplayTimedTextFromPlayer(GetLocalPlayer(),0,0,666,"WARNING : limitop reached for your test " + I2S(TEST_TO_DO))
                else
                    DisplayTimedTextFromPlayer(GetLocalPlayer(),0,0,666,"limitop not reached for your test " + I2S(TEST_TO_DO))
                endif
            #else
                TimerStart(CreateTimer(),PERIOD,true,function T)
            #endif
        }
       
    endlibrary


    locals vs globals in a theoretical scenario (1 declaration/setting + 2 read)

    I just realized that this test is a fail because of what i've said above, i keep it because theoretically globals are faster than locals but in a practical case i don't know yet, just because of the number of globals and their name length.
    I will do a better one when i will have the appropriate tool for it.

    Code (vJASS):
    library Benchmark initializer init {

        #define private TEST_TO_DO = 2  // 1 for locals test and 2 for globals test
        #define private PERIOD = 0.007 // depends your hardware configuration, if it lags to much try an higher value, if there is not enough fps drop try a lower one, btw the min is 0.0001    
       
        globals
            #for i (1,5000)
                integer J##i
            #endfor
        endglobals
               
        private nothing Test() {
       
            integer x
       
            #if  (TEST_TO_DO == 1)
           
                #for i (1,5000)
                    integer j##i = 1
                    x = j##i
                    x = j##i
                #endfor
           
            #elseif  (TEST_TO_DO == 2)
               
                #for i (1,5000)
                    J##i = 1
                    x = J##i
                    x = J##i
                #endfor
               
            #else
           
                PauseTimer(GetExpiredTimer()) ; DisplayTextToPlayer(GetLocalPlayer(),0,0,"invalid TEST_TO_DO")
               
            #endif
           
            // DisplayTextToPlayer(GetLocalPlayer(),0,0,"limit op not reached")
           
        }
       
        private nothing init() {
            TimerStart(CreateTimer(),PERIOD,true,function Test)
        }
       
    }


    Result : 30 fps for locals and 58 fps for globals (just starting to lost fps, my max is 60 fps)

    Conclusion : Since it's only a theoretical use i can't conclude yet

    PS : I'm open to all critics, comments and suggestions as long they are constructive.
     
    Last edited: Aug 23, 2011
  2. Troll-Brain

    Troll-Brain

    Joined:
    Apr 27, 2008
    Messages:
    2,372
    Resources:
    1
    JASS:
    1
    Resources:
    1
    locals vs globals with the same name length (1) and heavy usage (write)

    Code (vJASS):
    library Benchmark initializer init {

        #define private TEST_TO_DO = 2  // 1 for locals test and 2 for globals test
        #define private PERIOD = 0.003 // depends your hardware configuration, if it lags to much try an higher value, if there is not enough fps drop try a lower one, but be aware that the min is 0.0001    
       
        globals
            #for i (1,5000)
                integer J##i
            #endfor
            integer X
        endglobals
               
        private nothing Test() {
       
            #if  (TEST_TO_DO == 1)
           
                integer x
                #for i (1,20000)
                    x = 1
                #endfor
           
            #elseif  (TEST_TO_DO == 2)
               
                #for i (1,20000)
                    X = 1
                #endfor
               
            #else
           
                PauseTimer(GetExpiredTimer()) ; DisplayTextToPlayer(GetLocalPlayer(),0,0,"invalid TEST_TO_DO")
               
            #endif
           
            // DisplayTextToPlayer(GetLocalPlayer(),0,0,"limit op not reached")
           
        }
       
        private nothing init() {
            TimerStart(CreateTimer(),PERIOD,true,function Test)
        }
       
    }


    Result : 25 fps for locals and 45 fps for globals.
    Note that i have the same results with 10 000 globals declared :

    Code (vJASS):
        globals
            #for i (1,10000)
                integer J##i
            #endfor
            integer X
        endglobals


    In other words, the number of global variables doesn't matter.

    locals vs globals in a practical usage (local length =1 , global length = 2) with heavy usage (write)

    Code (vJASS):
    library Benchmark initializer init {

        #define private TEST_TO_DO = 1  // 1 for locals test and 2 for globals test
        #define private PERIOD = 0.003 // depends your hardware configuration, if it lags to much try an higher value, if there is not enough fps drop try a lower one, but be aware that the min is 0.0001
       
        globals
            #for i (2,5000)
                integer J##i
            #endfor
            integer J1
        endglobals
               
        nothing T() {
       
            #if  (TEST_TO_DO == 1)
           
                integer j
                #for i (1,20000)
                    j = 1
                #endfor
           
            #elseif  (TEST_TO_DO == 2)
               
                #for i (1,20000)
                    J1 = 1
                #endfor
               
            #else
           
                PauseTimer(GetExpiredTimer()) ; DisplayTextToPlayer(GetLocalPlayer(),0,0,"invalid TEST_TO_DO")
               
            #endif
           
            // DisplayTextToPlayer(GetLocalPlayer(),0,0,"limit op not reached")
           
        }
       
        private nothing init() {
            TimerStart(CreateTimer(),PERIOD,true,function T)
        }
       
    }


    Result : 34 fps for locals and 26 for globals.

    Conclusion : Globals are theoretically faster than locals in an heavy usage (like an huge loop), but not in a practical use, see the main post of this thread for more details.
    Note that i'm talking about heavy usage of the variables not the usual loops or classic usage in general, i will test them later.
     
    Last edited: Aug 19, 2011
  3. Troll-Brain

    Troll-Brain

    Joined:
    Apr 27, 2008
    Messages:
    2,372
    Resources:
    1
    JASS:
    1
    Resources:
    1
    testing the matter of the variable length name (write)

    Code (vJASS):
    library Benchmark initializer init {

        #define private TEST_TO_DO = 2  // 1 for short variable name and 2 for the longer name
        #define private PERIOD = 0.003 // depends your hardware configuration, if it lags to much try an higher value, if there is not enough fps drop try a lower one    
       
        globals
            #for i (1,20000)
                integer J##i
            #endfor
            integer J
        endglobals
               
        private nothing Test() {
       
            integer x
       
            #if  (TEST_TO_DO == 1)
           
                #for i (1,20000)
                    J = 1
                #endfor
           
            #elseif  (TEST_TO_DO == 2)
               
                #for i (1,20000)
                    J20000 = 1
                #endfor
               
            #else
           
                PauseTimer(GetExpiredTimer()) ; DisplayTextToPlayer(GetLocalPlayer(),0,0,"invalid TEST_TO_DO")
               
            #endif
           
            // DisplayTextToPlayer(GetLocalPlayer(),0,0,"limit op not reached")
           
        }
       
        private nothing init() {
            TimerStart(CreateTimer(),PERIOD,true,function Test)
        }
       
    }


    Result : 46 fps for the short name and 18 fps for the longer.
    Note that i have the same results with only 2 globals declared :

    Code (vJASS):
        globals
            integer J
            integer J20000
        endglobals


    In other words, the number of global variables doesn't matter (again).

    testing the matter of the function length name (write)

    Code (vJASS):
    library Benchmark initializer init {

        #define private TEST_TO_DO = 2  // 1 for short name test and 2 for long name test
        #define private PERIOD = 0.006 // depends your hardware configuration, if it lags to much try an higher value, if there is not enough fps drop try a lower one, but be aware that the min is 0.0001
               
        nothing S() {
        }
       
        nothing SuperLongName() {
        }
       
        nothing T() {
       
            #if  (TEST_TO_DO == 1)
           
                #for i (1,20000)
                    S()
                #endfor
           
            #elseif  (TEST_TO_DO == 2)
               
                #for i (1,20000)
                    SuperLongName()
                #endfor
               
            #else
           
                PauseTimer(GetExpiredTimer()) ; DisplayTextToPlayer(GetLocalPlayer(),0,0,"invalid TEST_TO_DO")
               
            #endif
           
           //  DisplayTextToPlayer(GetLocalPlayer(),0,0,"limit op not reached")
           
        }
       
        private nothing init() {
            TimerStart(CreateTimer(),PERIOD,true,function T)
        }
       
    }


    Result : 44 fps for the short name and 21 fps for the longer one

    Conclusion : The length name of variables and functions indeed does matter about the script efficiency.
     
    Last edited: Aug 19, 2011
  4. Troll-Brain

    Troll-Brain

    Joined:
    Apr 27, 2008
    Messages:
    2,372
    Resources:
    1
    JASS:
    1
    Resources:
    1
    Actually that's 1 write and 2 reads, but i can do more if you want, even if i bet that won't change that much.

    What do you suggest ? (1 write, 4 reads ? )

    Anyway i will do more tests , like hashtable vs array, GetHandleId + constant handle vs constant integer, but at very least 11 hours later from now.

    Also for all, feel free to post your own.
     
  5. Geries

    Geries

    Joined:
    Sep 13, 2010
    Messages:
    497
    Resources:
    7
    Models:
    6
    Packs:
    1
    Resources:
    7
    Nice job :) That I would see is Hashtables vs Global arrays, Hashtables vs Game Caches( due it is a table too ), BJ things vs non BJ things like

    Code (vJASS):
    function A takes integer a , integer b returns integer
         return a + b
    endfunction

    function B takes nothing returns nothing
         call DisplayTextToPlayer( Player( 0 ) , 0 , 0 , I2S( A( 1 , 1 ) ) )
    endfunction

    // VS

    function C takes nothing returns nothing
         call DisplayTextToPlayer( Player( 0 ) , 0 , 0 , I2S( 1 + 1 ) )
    endfunction

    and Reals vs Integers :)

    EDIT: and the ForGroup vs unit group looping( with FirstOfGroup )
     
  6. Bribe

    Bribe

    Joined:
    Sep 26, 2009
    Messages:
    7,478
    Resources:
    25
    Maps:
    3
    Spells:
    10
    Tutorials:
    3
    JASS:
    9
    Resources:
    25
    I can't imagine why unit group looping would be slower than ForGroup - ForGroup opens up
    a new thread for every unit.
     
  7. Magtheridon96

    Magtheridon96

    Joined:
    Dec 12, 2008
    Messages:
    6,017
    Resources:
    26
    Maps:
    1
    Spells:
    8
    Tutorials:
    7
    JASS:
    10
    Resources:
    26
    You don't need ForGroup if you're going to use the filter of the GroupEnumUnitsInRange function to manipulate the units :p

    Btw, are you sure ForGroup creates a new thread per unit?

    It's likely that integers are marginally faster :p (Meaning it wont matter much ^^)
    Reals need more memory than integers, so logically, they would be slower than integers :D
     
  8. Geries

    Geries

    Joined:
    Sep 13, 2010
    Messages:
    497
    Resources:
    7
    Models:
    6
    Packs:
    1
    Resources:
    7
    I know. Just cause this is a benchmark with FPS test then I am curious that how much slower.
     
  9. Bribe

    Bribe

    Joined:
    Sep 26, 2009
    Messages:
    7,478
    Resources:
    25
    Maps:
    3
    Spells:
    10
    Tutorials:
    3
    JASS:
    9
    Resources:
    25
    All code-based stuff opens up a new thread. In fact, there is a common.ai native (regrettably
    doesn't work because Blizzard cheated us on this one) which is called StartThread which
    takes a code argument.

    If you take a look at Nestharus' BigInt library, he evaluates a boolexpr and even that
    boolexpr has its own op limit which does not crash the thread where it was called from -
    indicating that it has a thread of its own. It wouldn't surprise me.

    The reason "executes" are so slow is becuase they allow waits.
     
  10. Magtheridon96

    Magtheridon96

    Joined:
    Dec 12, 2008
    Messages:
    6,017
    Resources:
    26
    Maps:
    1
    Spells:
    8
    Tutorials:
    7
    JASS:
    10
    Resources:
    26
    Well, since:

    Integers -> 32 bits (4 bytes)
    Reals -> (They're floats in WC3) ->
    32 bits + 3 bits per decimal digit

    I think that should be about right :)
    And since floats hold 7 decimal digits
    ->

    32 bits + 3 * 7 bits = 53 bits

    So, integers should be about 1.65625 times faster than reals :D
     
  11. Geries

    Geries

    Joined:
    Sep 13, 2010
    Messages:
    497
    Resources:
    7
    Models:
    6
    Packs:
    1
    Resources:
    7
    All right I made some benchmarks too:

    All value was tested in 10000 OP / sec for 10 seconds
    I was monitoring the CPU process too

    Reals VS Integers
    There were no difference in the FPS, real's benchmark took 1-3% more CPU

    BJs VS non BJs
    There were NO DIFFERENCE

    Hashtables VS Game Caches
    Well this benchmark was the most succesful. Game caches took 2-3x more CPU than hashtables. However there were no difference in the FPS

    Okey I made the same with 10x operations

    Reals VS Integers
    No difference again...

    BJs vs non BJs
    Finally. Difference. BJs FPS ~50FPS non BJs ~60FPS

    Hash VS GameCache
    Game caches became unhandleabe laggy( 2 FPS or less ) so It was not really took 10 seconds... was
    Hashtables better here, but while they freezed the computer while processing gamecaches wasn't.

    Conclusion: Reals not dangerous, however they can be unnaccure. Do not use game caches too much just if it needs. BJs does less harm than we tought. I say everyone use BJs as much as he want. The 10 FPS difference shown up at 100000 BJ operations
     
  12. Magtheridon96

    Magtheridon96

    Joined:
    Dec 12, 2008
    Messages:
    6,017
    Resources:
    26
    Maps:
    1
    Spells:
    8
    Tutorials:
    7
    JASS:
    10
    Resources:
    26
    It depends on what BJs you were using :p

    Are one-line BJs like GetLastCreatedUnit() inlined by JNGP? :S

    I'd say those results are impossible.
    It's like saying a function call has no overhead..

    Oh and when I said reals were slower than integers, it's quite marginal (obviously)
     
  13. Nestharus

    Nestharus

    Joined:
    Jul 10, 2007
    Messages:
    6,143
    Resources:
    8
    Spells:
    3
    Tutorials:
    4
    JASS:
    1
    Resources:
    8
    Hm... that's very different from what I had when deving Timer Tools.


    The 6 global sets in it completely crippled it (many global sets + global reads). Also, the 3 local declarations crippled it too (1 local read + 1 local write was a bit faster than declaring that extra local).



    Anyways... here's the next thing I'm wondering.. global lookups require a search, that's just normal to all programming languages. The bigger the scope, the longer the search. On TH when it was benched, more globals made global reads/writes slower than locals.

    What you should try is declaring half above the global var in question and half below to see if that makes a different. Do like x, y, z and test y.
     
  14. Magtheridon96

    Magtheridon96

    Joined:
    Dec 12, 2008
    Messages:
    6,017
    Resources:
    26
    Maps:
    1
    Spells:
    8
    Tutorials:
    7
    JASS:
    10
    Resources:
    26
    That makes sense Nestharus >:p
     
  15. Geries

    Geries

    Joined:
    Sep 13, 2010
    Messages:
    497
    Resources:
    7
    Models:
    6
    Packs:
    1
    Resources:
    7
    Believe me that I told :) Tell me one BJ I'll test it out. I used the example function BJ takes integer a , integer b returns integer

    About the reals: maths for computer like + - is easy for it. Also I have already noticed that reals after a time become unaccure they show different value than they has to.

    The function calls for the BJs are that game has to search that function and thats the only pluss in it.

    EDIT:

    Okey. You wanted. I choosed a very much used BJ
    TriggerRegisterAnyUnitEventBJ
    . The results now better for the BJs. Test made with 1200 op/sec.

    RESULT FOR NON BJ=48~50 FPS
    RESULT FOR BJ = ~45 FPS

    Thats the sad truth

    The test contained operation counting and trigger creating( local ) and destroy

    Alsooo If you don't null variable it will return epic fast memory usage increment
     
    Last edited: Aug 18, 2011
  16. Troll-Brain

    Troll-Brain

    Joined:
    Apr 27, 2008
    Messages:
    2,372
    Resources:
    1
    JASS:
    1
    Resources:
    1
    Probably because of the name length ?

    Well i think i've clearly show that declaring locals is slower than using a global, but it's not that simple, first i used "long" names, secondly i declared 5k of local variables ...
    And finally i didn't take handle locals which have to be nulled, well technically even globals have to be nulled to avoid a minor leak but it's only a memory leak not an handle id leak.
    http://www.thehelper.net/forums/sho...Found-Keeping-references-to-destroyed-objects.
    EDIT : Tested and the leak still exists with the newest patch.

    It's clearly not a real case, but i guess that a real case couldn't be correctly benchmarked, simply just because by the timer expiration by itself which should matter to much.
    I will try later with 52 local variables (a-Z) vs 52 globals with 2-3 name length, which is fair with an efficient script optimizer.

    2 characters : (63-11)*(63^(2-2))*(63-1) == 52*1*62 == 3224 combinations

    3 characters : (63-11)*(63^(3-2))*(63-1) == 52*63*62 == 203112 combinations, probably much more than enough for 99.999 % of wc3 maps.

    But i have to suggest this feature for cjass or make a script for myself which can use this special "base" "63" and generate words. (or anybody is welcome to provide a such script in the language you want)
    I've already told about making an optimizer with Bribe, but i stated that i forgot the idea of learning C, but i will learn it in a near feature, can't guess how much time i will take to make a beta version of this "awesome" optimizer though.
    Anyway at least i will do it for me, regardless when it will be finished or if something similar is already done ^^

    Nothing is normal in jass, hell the matter of variable name length is senseless ...

    Ok i will do it, but i don't think it won't change something, i remember Vexorian stated that the number of global variables didn't matter.
    Hell he is the guy who has made a preprocessor using a lot of globals :p

    I take in consideration other suggestions of tests, i just won't test BJ, because the useless are ... useless and the useful ones are ... useful, and if you care that much you still can inline them, but i would say that inline useful BJ such as TriggerRegisterAnyUnitEventBJ is totally pointless, that would just mean that you want to inline all your functions ...

    For all plz submit benchmark code, sorry but without it's just pointless.
     
    Last edited: Aug 24, 2011
  17. Troll-Brain

    Troll-Brain

    Joined:
    Apr 27, 2008
    Messages:
    2,372
    Resources:
    1
    JASS:
    1
    Resources:
    1
    Something really important :

    Theoretically globals are faster than locals (with the same name length), but in a practical use i don't know yet, i have explained it in the first thread and i will post more benchmarks.
     
    Last edited: Aug 24, 2011
  18. Troll-Brain

    Troll-Brain

    Joined:
    Apr 27, 2008
    Messages:
    2,372
    Resources:
    1
    JASS:
    1
    Resources:
    1
    I've improved and added some benchmarks, some others are coming.
     
  19. Troll-Brain

    Troll-Brain

    Joined:
    Apr 27, 2008
    Messages:
    2,372
    Resources:
    1
    JASS:
    1
    Resources:
    1
    testing the matter of the global variable place in the scope (write)

    Code (vJASS):
    library Benchmark initializer init {

        #define private PERIOD = 0.003 // depends your hardware configuration, if it lags to much try an higher value, if there is not enough fps drop try a lower one, but be aware that the min is 0.0001
       
        globals
            #for i (2,2500)
                integer J##i
            #endfor
            integer J1
            #for i (2501,5000)
                integer J##i
            #endfor
           
        endglobals
               
        nothing T() {
               
                #for i (1,20000)
                    J1 = 1
                #endfor
           
            // DisplayTextToPlayer(GetLocalPlayer(),0,0,"limit op not reached")
           
        }
       
        private nothing init() {
            TimerStart(CreateTimer(),PERIOD,true,function T)
        }
       
    }


    Result : 27 fps

    I've pretty much the same result with these global declarations :

    Code (vJASS):
        globals
            #for i (2,5000)
                integer J##i
            #endfor
            integer J1
           
        endglobals


    And :

    Code (vJASS):
        globals
            #for i (1,5000)
                integer J##i
            #endfor
           
        endglobals


    Conclusion : The place in the global scope doesn't matter.
     
  20. Troll-Brain

    Troll-Brain

    Joined:
    Apr 27, 2008
    Messages:
    2,372
    Resources:
    1
    JASS:
    1
    Resources:
    1
    Hashtable vs global array (write)

    code
    Code (vJASS):
    library Benchmark initializer init {

        #define private TEST_TO_DO = 1 // 1 for array test and 2 for hashtable test
        #define private PERIOD = 0.005 // depends your hardware configuration, if it lags to much try an higher value, if there is not enough fps drop try a lower one, btw the min is 0.0001
       
        globals
            integer array X1
            hashtable Ht
        endglobals
               
        nothing T() {
       
            #if  (TEST_TO_DO == 1)
           
                #for i (1,20000)
                    X1[8190] = 1
                #endfor
           
            #elseif  (TEST_TO_DO == 2)
               
                #for i (1,20000)
                    SaveInteger(Ht,1,8190,1)
                #endfor
               
            #else
           
                PauseTimer(GetExpiredTimer()) ; DisplayTextToPlayer(GetLocalPlayer(),0,0,"invalid TEST_TO_DO")
               
            #endif
           
             //DisplayTextToPlayer(GetLocalPlayer(),0,0,"limit op not reached")
           
        }
       
        private nothing init() {
            Ht = InitHashtable()
            TimerStart(CreateTimer(),PERIOD,true,function T)
        }
       
    }


    Result : With PERIOD == 0.02 i've no fps drop for globals (60) and 28 fps for the hashtable, to have 28 fps for globals i had to set PERIOD to 0.005.

    Conclusion : Hashtable is way slower than a global array (more than 20 times), when it's about to write them.
    So vJass extended arrays are probably even faster than hashtables but the global and code flood is a nightmare :p
    Though, now that i've made the write test it's not so true.


    Hashtable vs global array (read)

    code
    Code (vJASS):
    library Benchmark initializer init {

        #define private TEST_TO_DO = 1 // 1 for array test and 2 for hashtable test
        #define private PERIOD = 0.005 // depends your hardware configuration, if it lags to much try an higher value, if there is not enough fps drop try a lower one, btw the min is 0.0001
       
        globals
            integer array X1
            hashtable Ht
            integer X
        endglobals
               
        nothing T() {
       
            #if  (TEST_TO_DO == 1)
           
                #for i (1,20000)
                    X = X1[8190]
                #endfor
           
            #elseif  (TEST_TO_DO == 2)
               
                #for i (1,20000)
                    X = LoadInteger(Ht,1,2)
                #endfor
               
            #else
           
                PauseTimer(GetExpiredTimer()) ; DisplayTextToPlayer(GetLocalPlayer(),0,0,"invalid TEST_TO_DO")
               
            #endif
           
             //DisplayTextToPlayer(GetLocalPlayer(),0,0,"limit op not reached")
           
        }
       
        private nothing init() {
            Ht = InitHashtable()
            X1[2] = 3
            SaveInteger(Ht,1,2,3)
            TimerStart(CreateTimer(),PERIOD,true,function T)
        }
       
    }


    Result : To get 5 fps i have to use the 0.005 for global read and 0.018 for hashtable read.

    Conclusion : Hashtable write seems to be more than 3.6 times slower than a global array write.
    Not so much, it wouldn't worth the overhead of vJass extended arrays.

    But plz care that i've inlined the use of the hashtable.
    Because of the 256 hashtable limit, you would use one hashtable dynamically instead, such as the vJass library Table which will slow down the hashtable usage.
    Also i haven't tried if the hashtable usage slow down significantly when the hashtable is full of data. (could be done with future tests)
     
    Last edited: Sep 2, 2011