Luth
Lex Luthor!
- Reaction score
- 41
From time to time, I get bashed for using BJ ("non-native") functions in my triggers. I dont mind, as I know what BJs are and how they work. Plus, if I understand Vex's optimizer, it removes the BJs anyway, so I care even less.
But it seems that some people can get fixated on the idea that non-native functions makes it a bad trigger, and that seems silly to me. Why? In general, a BJ function is one that simply calls another function. For example:
True, this means that the computer must do more work to process a BJ func than a native one! How much more work? ... So little that you'd never notice it.
But you dont have to take my word for it. I decided to test for myself how bad these nasty non-natives are. I devised this simple test-map (attached below) to put both BJ and non-BJ functions to a time trial.
The BJ test looks like this (left in the original GUI):
The non-BJ code looks like this:
You'll notice that the two triggers are identical, save for the two loop functions, "UnitAddAbility(BJ)" and "UnitRemoveAbility(BJ)". The test starts by setting the Time Of Day to 12.00, then calls these two functions 100,000 times, pausing for 0.50 every 3,000 iterations, then spits out the current time of day when it is complete. The tests ran for aprox 20ish seconds, due mainly to the Wait statements, which still provides 10,000 test calls per second.
In a single map execution, I ran each test six times, and obtained the following results (all measurements are in default wc3 game seconds, which are considerably less than one RL second [aprox 0.0111 rl sec]):
An average difference of 0.0008 game seconds, or 0.0000089 real seconds. While twelve tests may not be enough to convince a statistician, the numbers were so very close that they did convince me. 200,000 BJ calls took the same amount of time as 200,000 Non-BJ calls, which is as expected.
Normally, I'm the kind of guy who tries to eek out every bit of performance from code (and script), and I'm not bashing those who never use a non-native function, but I think the evidence is plain enough to see. There are far more troublesome things to worry about in your triggers than whether or not you're using non-native functions, as, in the end, they're just as good as natives. But, as stated above, dont take my word for it, test it yourself.
But it seems that some people can get fixated on the idea that non-native functions makes it a bad trigger, and that seems silly to me. Why? In general, a BJ function is one that simply calls another function. For example:
Code:
function FooBJ takes unit A, integer B returns boolean
return Foo(B, A)
endfunction
But you dont have to take my word for it. I decided to test for myself how bad these nasty non-natives are. I devised this simple test-map (attached below) to put both BJ and non-BJ functions to a time trial.
The BJ test looks like this (left in the original GUI):
Code:
Actions
Game - Set the time of day to 12.00
For each (Integer A) from 1 to 100000, do (Actions)
Loop - Actions
Unit - Add Berserk to Peasant 0000 <gen>
Unit - Remove Berserk from Peasant 0000 <gen>
If (All Conditions are True) then do (Then Actions) else do (Else Actions)
If - Conditions
((Integer A) mod 3000) Equal to 0
Then - Actions
Wait 0.50 seconds
Else - Actions
Game - Display to (All players) the text: (String((In-game time of day)))
The non-BJ code looks like this:
Code:
function Trig_No_BJ_Actions takes nothing returns nothing
call SetTimeOfDay( 12 )
set bj_forLoopAIndex = 1
set bj_forLoopAIndexEnd = 100000
loop
exitwhen bj_forLoopAIndex > bj_forLoopAIndexEnd
call UnitAddAbility( gg_unit_hpea_0000, 'Absk' )
call UnitRemoveAbility( gg_unit_hpea_0000, 'Absk' )
if ( ModuloInteger(GetForLoopIndexA(), 3000) == 0 ) then
call TriggerSleepAction( 0.50 )
endif
set bj_forLoopAIndex = bj_forLoopAIndex + 1
endloop
call DisplayTextToForce( GetPlayersAll(), R2S(GetTimeOfDay()) )
endfunction
You'll notice that the two triggers are identical, save for the two loop functions, "UnitAddAbility(BJ)" and "UnitRemoveAbility(BJ)". The test starts by setting the Time Of Day to 12.00, then calls these two functions 100,000 times, pausing for 0.50 every 3,000 iterations, then spits out the current time of day when it is complete. The tests ran for aprox 20ish seconds, due mainly to the Wait statements, which still provides 10,000 test calls per second.
In a single map execution, I ran each test six times, and obtained the following results (all measurements are in default wc3 game seconds, which are considerably less than one RL second [aprox 0.0111 rl sec]):
Code:
BJ Non-BJ
13.045 13.043
13.038 13.034
13.025 13.022
13.016 13.019
13.016 13.016
13.009 13.010
Avg BJ time: 13.0248
Avg Non-BJ time: 13.0240
An average difference of 0.0008 game seconds, or 0.0000089 real seconds. While twelve tests may not be enough to convince a statistician, the numbers were so very close that they did convince me. 200,000 BJ calls took the same amount of time as 200,000 Non-BJ calls, which is as expected.
Normally, I'm the kind of guy who tries to eek out every bit of performance from code (and script), and I'm not bashing those who never use a non-native function, but I think the evidence is plain enough to see. There are far more troublesome things to worry about in your triggers than whether or not you're using non-native functions, as, in the end, they're just as good as natives. But, as stated above, dont take my word for it, test it yourself.