HomeUser Control Panel (unavailable in archive)ForumsTutorialsArt GalleryResourcesMaps

Do Booleans leak?

01-13-2008, 05:10 AM#1
darkwulfv
Name says it all. I know Boolexprs leak (to some extent, or something)...

Eg:

Collapse JASS:
function blah takes nothing returns nothing
  local boolean b1 = booleanfunctionhere
  //actions, etc.
  endfunction
//ending function without nulling/destroying/whatever the boolean

I'm wondering, because it would make GroupEnum filters and large conditions easier to just do return b1 and b2 and b3 and (b4 or b5) or (b6 and b7) and stuff like that, instead of insanely long function, and, function, and, function, or, function, and, etc.

Thanks.
EDIT: Yay for palendromic post count. (1881)
01-13-2008, 05:19 AM#2
HINDYhat
As far as I know, no.

The only types that leak in Warcraft III would be handles (every type besides integer, real, boolean, code, and string), with the exception of string leakage. So declaring a boolean like you just did might as well be declaring an integer, which won't leak at all.
01-13-2008, 05:19 AM#3
darkwulfv
Awesome, thanks a bunch. Makes my life hellalot easier.
01-13-2008, 07:42 AM#4
Malf
Here's a tip, anything that can't be nulled don't leak. Except for strings that is.
01-13-2008, 08:10 AM#5
Pyrogasm
And it's a primitive (if that means anything to you).
01-13-2008, 09:48 AM#6
cohadar
Boolexpr is a pointer to a function that returns a boolean,
and since you cannot destroy a function it does not leak.

I am not so sure about Boolexpr's you create from other boolexpr's like this

set C = And(A, B) , D = Or(A, B)
01-13-2008, 10:11 AM#7
Malf
grim001 pointed out you don't even need boolexpr variables, just use the Condition() or Filter() functions directly.

Btw, And() and Or() are the next lamest functions besides DoNothing()

EDIT:

Wait, what the fuck am I talking about? The thread's about booleans not boolexprs ._.
01-13-2008, 11:31 AM#8
cohadar
Quote:
Originally Posted by Malf
Wait, what the fuck am I talking about? The thread's about booleans not boolexprs ._.

Going off-topic like that, shame on you.
01-13-2008, 12:47 PM#9
HINDYhat
Quote:
Originally Posted by Malf
Here's a tip, anything that can't be nulled don't leak. Except for strings that is.
And code, and boolexpr, and players, and basically any other type that always returns a constant value. Possibly lightnings, not sure about that, since their handle ID is really messed up.
01-13-2008, 03:36 PM#11
moyack
Definitely not. In fact we should take this advantage to do filters in this way:

Collapse JASS:
private function GetEnemies takes nothing returns boolean
    local boolean b1 = IsUnitType(GetFilterUnit(), UNIT_TYPE_FLYING) == false
    local boolean b2 = IsUnitAlly(GetFilterUnit(), bj_groupEnumOwningPlayer)
    local boolean b3 = GetWidgetLife(GetFilterUnit()) > 0.405
    local boolean b4 = not IsUnitProjectile(GetFilterUnit())
    local boolean b5 = IsUnitInRange(bj_meleeNearestMine, GetFilterUnit(), Radius) 
    local boolean b6 = IsUnitInRange(bj_groupRandomCurrentPick, GetFilterUnit(), Radius)
    return b1 and b2 and b3 and b4 and b5 and b6
endfunction

It's very readable and comfortable.
01-13-2008, 03:48 PM#12
Vexorian
Types don't really leak, it is functions and what they return what would leak if you don't handle them correctly.

For example Condition() and Filter() don't "leak", since they always return the same value for every function. But And() does.
01-13-2008, 04:37 PM#13
rain9441
@moyack:

Thats not a good way of doing it. In boolean evaluations when dealing with and's as well as Or's they are slightly optimized because they can just stop evaluating when they know the value is not going to change.

E.g:

if ( 1 == 2 and SomeReallyHeftyFunctionThatLags() ) then
...

That laggy function will never be evaluated.

Similar to ORs

if ( 1 == 1 or SomeReallyHeftFunctionThatLags() ) then

Again, that laggy function won't be evaluated.

In your case, if the unit type is flying then you are unnecessarily causing it to call IsUnitAlly, GetWidgetLife, IsUnitProjectile, IsUnitInRange, IsUnitInRange, etc...

But thats just my opinion. I have a REALLY long set of if's in my Autocast Filter, and every single one of them is like this: if ( ShouldCheckIfUnitTypeIsBlah and IsUnitType(unit, Blah) == false ) then return endif. Now theres no need to go ahead and run 50 other checks on the unit.

Also, put common cases first, rare cases checked last, also improves performance.

But then again, this performance is so minute that it really probably doesnt matter 99% of the time.

Its almost the same as the concept of having 80 triggers with (GetSpellAbilityId() == somevalue) as condition compared to one trigger with a hash lookup of GetSpellAbilityId() and an evaluate call. Very small performance gain, and only when the execution is being called very frequently.
01-13-2008, 05:22 PM#14
moyack
Quote:
Originally Posted by rain9441
@moyack:

Thats not a good way of doing it. In boolean evaluations when dealing with and's as well as Or's they are slightly optimized because they can just stop evaluating when they know the value is not going to change.

E.g:

if ( 1 == 2 and SomeReallyHeftyFunctionThatLags() ) then
...

That laggy function will never be evaluated.

Similar to ORs

if ( 1 == 1 or SomeReallyHeftFunctionThatLags() ) then

Again, that laggy function won't be evaluated.

In your case, if the unit type is flying then you are unnecessarily causing it to call IsUnitAlly, GetWidgetLife, IsUnitProjectile, IsUnitInRange, IsUnitInRange, etc...

But thats just my opinion. I have a REALLY long set of if's in my Autocast Filter, and every single one of them is like this: if ( ShouldCheckIfUnitTypeIsBlah and IsUnitType(unit, Blah) == false ) then return endif. Now theres no need to go ahead and run 50 other checks on the unit.

Also, put common cases first, rare cases checked last, also improves performance.

But then again, this performance is so minute that it really probably doesnt matter 99% of the time.

Its almost the same as the concept of having 80 triggers with (GetSpellAbilityId() == somevalue) as condition compared to one trigger with a hash lookup of GetSpellAbilityId() and an evaluate call. Very small performance gain, and only when the execution is being called very frequently.
Your suggestions are quite interesting. I like to do in this way for debugging, but I was convinced that all the functions were evaluated it doesn't matter the result was false before...

Anyways, I like your idea of grouping first the fastest comparisons and later the slowest (First native functions, then custom functions).
01-13-2008, 07:30 PM#15
Ammorth
I would group the booleans as those which would fail most often. That way it can exclude most of the units/choices/options on the first check instead of slowing filtering through them.