HomeUser Control Panel (unavailable in archive)ForumsTutorialsArt GalleryResourcesMaps

Location stack vs FirstOfGroup iteration vs ForGroup

07-17-2006, 01:22 PM#1
Vexorian
Collapse common:
function xxX takes nothing returns nothing
 local integer i=5000
    set udg_log=0
    loop
        exitwhen(i<=0)
        call ExecuteFunc("yyY")
        set i=i-1
    endloop
    call BJDebugMsg("!"+I2S(udg_log))




endfunction

//===========================================================================
function AddToList takes nothing returns nothing
   set udg_locgroup=Location(CS_h2r(GetEnumUnit()),CS_h2r(udg_locgroup))
endfunction



function InitTrig_Untitled_Trigger_001 takes nothing returns nothing
set udg_allunits=GetUnitsInRectAll(bj_mapInitialPlayableArea)
set udg_locgroup=null
    call ForGroup(udg_allunits,function AddToList)
    set gg_trg_Untitled_Trigger_001 = CreateTrigger(  )
    call TriggerRegisterPlayerEventEndCinematic( gg_trg_Untitled_Trigger_001, Player(0) )
    set udg_act=TriggerAddAction( gg_trg_Untitled_Trigger_001, function xxX )
endfunction



benchs:
ForGroup
2.81 seconds
Collapse JASS:
function zzZ takes nothing returns nothing
   set bj_forLoopAIndex=bj_forLoopAIndex+1
endfunction

function yyY takes nothing returns nothing
    set bj_forLoopAIndex=0
    call ForGroup(udg_allunits,function zzZ)
    if (bj_forLoopAIndex==60) then
        set udg_log=udg_log+1
    endif
endfunction
Location Stack
4.21 seconds
Collapse JASS:
function yyY_locs takes nothing returns nothing
 local location t=udg_locgroup
 local unit p
    set bj_forLoopBIndex=0

    loop
        exitwhen (t==null)
        set bj_forLoopBIndex=bj_forLoopBIndex+1
        set p=GetLocationX_Unit(t)


        set t=GetLocationY_Loc(t)
        
    endloop
    if (bj_forLoopBIndex==60) then
        set udg_log=udg_log+1
    else

    endif

 set p=null
endfunction
FirstOfGroup Iteration
6.31seconds
Collapse JASS:

function yyY takes nothing returns nothing
 local group g=CreateGroup()
 local unit p
    call GroupAddGroup(udg_allunits,g)
    set bj_forLoopAIndex=0
    loop
        set p=FirstOfGroup(g)
        exitwhen (p==null)
        call GroupRemoveUnit(g,p)
        set bj_forLoopAIndex=bj_forLoopAIndex+1
        
    endloop
    call DestroyGroup(g)
    if (bj_forLoopAIndex==60) then
        set udg_log=udg_log+1
    endif

 set p=null
endfunction

There were 60 preplaced units in the map
07-17-2006, 01:59 PM#2
Mezzer
I'm sorry but I don't feel like interpreting that, can you just give a shot summary of what you were testing there?
07-17-2006, 02:03 PM#3
Vexorian
ForGroup is fast.
A location-based linked list of units is 2x times slower than ForGroup
Using FirstOfGroup inside a loop to iterate through a group is 3x times slower than a ForGroup.

As a matter of fact I just replaced the caster system's movement group with a loc stack and the deal is now faster than ever. The lack of lag in the inferno spell is unbelievable!.
07-17-2006, 02:08 PM#4
Mezzer
I got the fast part, I was asking what you were testing there, as in, what were you basing your results on? A read/write thing or?
07-17-2006, 02:23 PM#5
Vexorian
counting the number of units in the group/stack
07-17-2006, 03:01 PM#6
Mezzer
Oh, I thought this was related to your other tests that you were doing lately with locations. Well, good to know anyway
07-17-2006, 04:13 PM#7
Rising_Dusk
So it took 7 seconds to count 60 preplaced units?
Or does that mean counting 60 units 5000 times took 7 seconds?
Are you sure?

I've been counting heavy amounts of units in my map and running through groups with FirstOfGroup() for awhile and it runs REALLY fast.
So I don't know..
07-17-2006, 07:13 PM#8
PipeDream
In my own tests where destruction was OK, as it quite often is, I found FirstOfGroup iteration marginally faster than ForGroup. You should probably test using GroupAddUnit with a swap at the end, as GroupAddGroup is a blizzard.j with a separate call to ForGroup.
07-17-2006, 07:14 PM#9
Vexorian
5000 times, the code is very explicit. Comparing without keeping the group would have been unfair considering that both stacks and ForGroup don't need to destroy the group.

Using GroupAddUnit would have been lame cause it requires you to update the original variables that point to the group. If I use ForGroup to add the units from a group to another I am still using ForGroup so it would at least take twice the time of ForGroup.
07-17-2006, 07:26 PM#10
PipeDream
It's not unfair, it's the best they can do at a specific extremely common application.
Using groupaddunit and swapping groups is much faster than forgroup. For me, it looks like 7s->4s.
Collapse JASS:
function yyY takes nothing returns nothing
 local group g=CreateGroup()
 local unit p
//    call GroupAddGroup(udg_allunits,g)
    set bj_forLoopAIndex=0
    loop
        set p=FirstOfGroup(udg_allunits)
        exitwhen (p==null)
        call GroupRemoveUnit(udg_allunits,p)
    call GroupAddUnit(g,p)
        set bj_forLoopAIndex=bj_forLoopAIndex+1
        
    endloop
    call DestroyGroup(udg_allunits)
    set udg_allunits = g
    set g = null
    if (bj_forLoopAIndex==60) then
        set udg_log=udg_log+1
    endif
endfunction
07-17-2006, 09:26 PM#11
Vexorian
It is unfair because it does not have the same functionality as ForGroup. That one requires you to update every pointer to the group and that's lame
07-17-2006, 11:02 PM#12
Sharingan
Excuse me...
What does ForGroup do?
07-17-2006, 11:24 PM#13
SentryIII
Since those times represent the amount of time to loop though 60 units 5000 times, here's the times for looping though 60 units once (for those who are lazy):

ForGroup: 0.000562 seconds (0.562 milliseconds)
Location Stack: 0.000842 seconds (0.842 milliseconds)
FirstOfGroup: 0.001262 seconds (1.262 milliseconds)

These numbers are closer to what we would have in any WC3 map. I use FirstOfGroup iterations extensively and the max amount of units that I iterate though would be 40, so I wouldn't bother switching to using ForGroup.

BTW Vexorian, mind posting the specs of the comp you tested this on?


Quote:
Originally Posted by Sharingan
Excuse me...
What does ForGroup do?

It's basically this trigger action:

Trigger:
Unit Group - Pick every unit in (Units in (Playable map area)) and do (Do nothing)
07-17-2006, 11:59 PM#14
emjlr3
how on earth did u measure that time?
07-18-2006, 02:47 AM#15
Vexorian
maybe he just divided the values I gave with 5000.

Anyways if you don't need the group anymore, then it is better to use FirstOfGroup

Quote:
ForGroup: 0.000562 seconds (0.562 milliseconds)
Location Stack: 0.000842 seconds (0.842 milliseconds)
FirstOfGroup: 0.001262 seconds (1.262 milliseconds)
That's kind of a simplist way to look at it, thing is that the slightest difference is important if you are inside a 0.04 seconds timer. The good thing is that Location Stacks are decently fast, can store other things that are not units and don't have FirstOfGroup disadvantage.