GetEnumUnit() vs. local unit u

Troll-Brain

You can change this now in User CP.
Reaction score
85
I also did "a long time before", but didn't find any test code, that's why i've posted one.

Btw it leaks for GroupEnum..., but not for TriggerRegisterPlayerUnitEvent, maybe it leaks for other things, i dunno.
So always using a boolexpr which return true instead of a null boolexpr would be probably a good standard, or someone has to test all functions :p
 

Troll-Brain

You can change this now in User CP.
Reaction score
85
I still see no proof. I'd need a test map with the handle count increasing or a copy/paste script that does the same. I'd just like this claim substantiated or dismissed, that's all.
Well, you can use an handle counter it will be the same, but anyway i don't really care that you don't believe it.
 

Viikuna

No Marlo no game.
Reaction score
265
It doesnt leak handles, but you should notice that performance loss if you try calling many GroupEnums with null boolexpr.

Still, its not really a problem, because it is easy to use some global boolexpr which always returns true.

edit. I tried it, and there is little performance drop after about 25 000 null boolexprs calls.. Well, hm.. I think I will test this again.
 

Narks

Vastly intelligent whale-like being from the stars
Reaction score
90
lawl, you are talking about groups because I used a group function as an example?
 

Vexorian

Why no custom sig?
Reaction score
187
A local is only faster if you do like 5 or more calls to the same GetEnumUnit()/GetFilterUnit() . Nevertheless, it won't really matter. I use a local when I use the same native more than once just because it is easier to type...

ForGroup is unnecessary in reality, just use a filter inside the GroupEnum functions.

The FirstOfGroup non-sense is slower than using ForGroup, you can be sure of it. However, with a GroupEnum+filter you can even get rid of the ForGroup itself.

Nevertheless, if you reach to a point in which these things matter speedwise, your map is already fast enough and you should focus on making a good map instead of increasing the framerate by 0.003
 

Jesus4Lyf

Good Idea™
Reaction score
397
Unsubstantiated claims make me want to test things. >_<
So I had to. :(
JASS:
globals
    group somegroup=CreateGroup()
endglobals
private function Code1 takes nothing returns nothing
    local unit u
    call GroupEnumUnitsInRange(somegroup,0,0,512.0,null)
    loop
        set u=FirstOfGroup(somegroup)
        exitwhen u==null
        call GroupRemoveUnit(somegroup,u)
        // do things
    endloop
endfunction

function associated takes nothing returns nothing
    local unit u=GetEnumUnit()
    // do things
    set u=null
endfunction
private function Code2 takes nothing returns nothing
    local unit u
    call GroupEnumUnitsInRange(somegroup,0,0,512.0,null)
    call ForGroup(somegroup,function associated)
    call GroupClear(somegroup)
endfunction
Once again, as usual, benchmarks are for the curious, not the speed freaks.

>The FirstOfGroup non-sense is slower than using ForGroup, you can be sure of it.

My benchmarks show FirstOfGroup is 24% faster (which is insignificant really, don't get me wrong, we're talking 2 nanoseconds on my computer for the whole loop). So I disagree that "you can be sure of it". That was without global carry variables.
JASS:
function associated takes nothing returns boolean
    local unit u=GetFilterUnit()
    // do things involving some carry
    set u=null
    return false
endfunction
private function Code2 takes nothing returns nothing
    set somecarry=null // Set it to some unit like a caster.
    call GroupEnumUnitsInRange(somegroup,0,0,512.0,Condition(function associated))
endfunction
Using a filter is 14% faster than a first of group loop. Keep in mind to gain this ridiculously small efficiency increase (about 1 nanosecond for the whole loop on my slow computer) the writer needs to use carry globals instead of referring to the data already avilable in the caller. This can be unstable due to possible recursion (don't laugh) and otherwise I consider it just too much of a pain to be worth while. I like local access.

But wait, there's more! That was with 5 units being enumerated. I found that if you increase it, first of group loops become faster. At 9 units they are within margin of error of eachother, below that the filters are faster, above that the first of group loops are faster.

Using a global instead of Condition(function x) each time changed it to 10 units being the break even point.

>you should focus on making a good map instead
Yep.
My consensus? Go use the FoG loops. Local access, code readability and reliability ftw. But the info is here so people can derive whatever conclusion they like from it, not so we can now argue about which conclusion everyone should derive. I'd be happy with seeing anything but ForGroup used, but I think the filter thing is ugly. XD

PS. The usual disclaimers about benchmarks: They can vary and stuff. We're talking tiny margins here anyway. :)
 

Troll-Brain

You can change this now in User CP.
Reaction score
85
About the performance, i guess it's because you use a local, what are the results if you use directly GetFilterUnit() instead ?
 

Vexorian

Why no custom sig?
Reaction score
187
Like you said it doesn't matter, and that's exactly what I said before.

Both FirstOfGroup loops and ForGroup are stuff I learned to hate. First of all, FirstOfGroup is an awful hack. Second, ForGroup encourages the idea that groups should be used beyond just doing enumerations which I disagree with after many disease cloud related handle stack corruptions that came after the use of groups.

A boolexpr with enum is shorter and easier to read anyway.
 
General chit-chat
Help Users
  • No one is chatting at the moment.

      The Helper Discord

      Members online

      No members online now.

      Affiliates

      Hive Workshop NUON Dome World Editor Tutorials

      Network Sponsors

      Apex Steel Pipe - Buys and sells Steel Pipe.
      Top