• 🏆 Texturing Contest #33 is OPEN! Contestants must re-texture a SD unit model found in-game (Warcraft 3 Classic), recreating the unit into a peaceful NPC version. 🔗Click here to enter!
  • It's time for the first HD Modeling Contest of 2024. Join the theme discussion for Hive's HD Modeling Contest #6! Click here to post your idea!

◊◊◊ vJass Script Optimization Workshop ◊◊◊

Status
Not open for further replies.
I'm dedicating this thread to optimizing vJass scripts.
Jass is a language fast enough to make a realtime game, but isn't as fast as C++ for example.
That's why optimizations are critical.

If you need me to optimize a script for you, just post it here.

You must post your request using this form:

- Code: <Insert code here>
- Time: <How much time will you give me to work on it> ("Now" is unacceptable :>)

[highlight]Converted GUI code is frowned upon![/code]
I'm not saying it won't be accepted though..

Thank you for reading.

~Magtheridon96
 

Dr Super Good

Spell Reviewer
Level 63
Joined
Jan 18, 2005
Messages
27,178
Jass is a language fast enough to make a realtime game, but isn't as fast as C++ for example.
No its not... Unless you mean a game like for the NES which it might barely be able to on modern processors.

JASS:
function CountPlayersInForceBJ takes force f returns integer
    set bj_forceCountPlayers = 0
    call ForForce(f, function CountPlayersInForceEnum)
    return bj_forceCountPlayers
endfunction
As function calls in JASS have a stupidly high overhead, it is obviously an optimization to inline that code.

Be aware you would have to declare the local before inlining the function and setting the local.

It might be faster to inline and use bj_forceCountPlayers up to a certain point (as the name is very long).

this brings up a further optimization where the whole enum called function could be optimized to use a shorter variable name for bj_forceCountPlayers.
 
Level 8
Joined
Apr 26, 2011
Messages
403
do you have a link for reading about which function/operation have higher/lower overhead ?


for example, compare follow operation :
- function call (with simple operation, eg set i = i +1 )
- create group by select unit from map
- create point by unit's position
- loop throught 100 units for nothing
- check unit's property (like current health)
etc
 
Level 8
Joined
Apr 26, 2011
Messages
403
which one is faster ?

local unit u = GetTriggerUnit() //or GetEnteringUnit()
function_A(u)
function_B(u)
GroupAddUnit (group_a, u)
GroupRemoveUnit(group_b, u)
set u = null

vs

function_A( GetTriggerUnit())
function_B( GetTriggerUnit())
GroupAddUnit (group_a, GetTriggerUnit())
GroupRemoveUnit(group_b, GetTriggerUnit())
 
Level 8
Joined
Apr 26, 2011
Messages
403
how about this ?
Code:
function InitTrig_WarpGroup_Left_JASS takes nothing returns nothing
    set gg_trg_WarpGroup_Left_JASS = CreateTrigger(  )
    call TriggerRegisterEnterRectSimple( gg_trg_WarpGroup_Left_JASS, gg_rct_1 )
    call TriggerRegisterEnterRectSimple( gg_trg_WarpGroup_Left_JASS, gg_rct_2 )
    call TriggerRegisterEnterRectSimple( gg_trg_WarpGroup_Left_JASS, gg_rct_3 )
    call TriggerRegisterEnterRectSimple( gg_trg_WarpGroup_Left_JASS, gg_rct_4 )
    call TriggerAddCondition( gg_trg_WarpGroup_Left_JASS, Condition( function Trig_WarpGroup_Left_JASS_Conditions ) )
    call TriggerAddAction( gg_trg_WarpGroup_Left_JASS, function Trig_WarpGroup_Left_JASS_Actions )
endfunction

I know TriggerRegisterEnterRectSimple can be shorten, but I don't know how to put them together

Code:
function TriggerRegisterEnterRectSimple takes trigger trig, rect r returns event
    local region rectRegion = CreateRegion()
    call RegionAddRect(rectRegion, r)
    return TriggerRegisterEnterRegion(trig, rectRegion, null)
endfunction
 
Level 29
Joined
Mar 10, 2009
Messages
5,016
and, should I remove TriggerAddAction, and put all code inside TriggerAddCondition ?

how much faster for put code inside condition ? (1%, 10% or 50%)

it depends upon your usage...if the calling of locals/variables cannot be avoided in Condition 'ONLY', then I suggest using the two (Condition and Action), just like spell filtering...but conditions are faster coz they go 'first'...
 
D:>

I'm the one that's supposed to be helping :mad:

Tips:

Please use jass tags next time.. code tags are for C++ or anything else that we don't have tags for like Java.

Mags, you've created like this one before but eventually you abandoned it, what's next?...

Nes ruined it :p

and, should I remove TriggerAddAction, and put all code inside TriggerAddCondition ?

how much faster for put code inside condition ? (1%, 10% or 50%)

TriggerAddAction is much slower than TriggerAddCondition (Not much of a difference but since TriggerExecute was recently proven to be about 3x slower than TriggerEvaluate, using conditions instead of actions is obviously better and faster.

edit

JASS:
function InitTrig_WarpGroup_Left_JASS takes nothing returns nothing
    set gg_trg_WarpGroup_Left_JASS = CreateTrigger(  )
    call TriggerRegisterEnterRectSimple( gg_trg_WarpGroup_Left_JASS, gg_rct_1 )
    call TriggerRegisterEnterRectSimple( gg_trg_WarpGroup_Left_JASS, gg_rct_2 )
    call TriggerRegisterEnterRectSimple( gg_trg_WarpGroup_Left_JASS, gg_rct_3 )
    call TriggerRegisterEnterRectSimple( gg_trg_WarpGroup_Left_JASS, gg_rct_4 )
    call TriggerAddCondition( gg_trg_WarpGroup_Left_JASS, Condition( function Trig_WarpGroup_Left_JASS_Conditions ) )
    call TriggerAddAction( gg_trg_WarpGroup_Left_JASS, function Trig_WarpGroup_Left_JASS_Actions )
endfunction

->

JASS:
function InitTrig_WarpGroup_Left_JASS takes nothing returns nothing
    local trigger t = CreateTrigger()
    local region r = CreateRegion()
    call RegionAddRect(r,gg_rct_1)
    call RegionAddRect(r,gg_rct_2)
    call RegionAddRect(r,gg_rct_3)
    call RegionAddRect(r,gg_rct_4)
    call TriggerRegisterEnterRegion(t,r,null)
    call TriggerAddCondition(t,Condition(function Trig_WarpGroup_Left_JASS_Actions))
    set t = null
    set r = null
endfunction


In the function Trig_WarpGroup_Left_Jass_Actions, you should include an if/then/endif block for the conditions and return false at the end of the function.
Please, next time, give me the complete code.. I can't instruct you like this because you might do something wrong and come back to complain :/
Also, don't forget to erase the Conditions function since you don't need it..
 
Level 8
Joined
Apr 26, 2011
Messages
403
most of my code are still GUI, I will post more after I rewrite them in JASS.

got a few question relate to optimization

Question 1:

JASS:
set gg_trg_WarpGroup_Left_JASS = CreateTrigger(  )
local trigger t = CreateTrigger()

when do "gg_trg_WarpGroup_Left_JASS" declared ? do I ever need this "variable" again ?

Question 2:
I notice "CountUnitsInGroup()" is a loop function, it loop loop through every unit to count them :fp:

do it mean this function is really slow ? (eg same speed as "for every unit in unit group" ? )

because I use it quiet often as condition :


JASS:
if (CountUnitsInGroup(unit_group) > 0 ) then
  do something
if( CountUnitsInGroup(creep_group) == 0) then
  do lots of other things

and
max qty for unit_group = 200's :grin:
max qty for creep_group = 360-400 :grin:


Question 3:

I have 20-100 trigger with custom ability. half of them similar to this :

  • Triple Attack
    • Events
      • Unit - A unit Is attacked
    • Conditions
      • (Unit-type of (Attacking unit)) Equal to Hydra fighter
      • (Mana of (Attacking unit)) Equal (Max mana of (Attacking unit))
    • Actions
      • Unit - cast ability blah blah // or create dummy_unit and cast custom ability
how much difference if :
- combine 50 trigger into 1, with lots of if..else in condition, as well as lots of if..else in action
vs
- don't combine, leave 50 trigger with simple condition & fast action
 
1- gg_trg_WarpGroup_Left_JASS was declared when you created a trigger called WarpGroup Left Jass
Just use a local trigger instead.

2- CountUnitsInGroup isn't so bad.. it uses a ForGroup call, not a loop.
Inlining it may be slightly cumbersome though.

3- Keep the triggers in their current state.

Listen dude,

[highlight]Converted GUI code is frowned upon![/code]

Also, I only do vJass here.
GUI is not really my thing.

This thread is for people to post vJass LIBRARIES and shit for me to optimize.
Optimizing bits of code is hard because I have to instruct you to change other parts of your code.

I'd suggest using the Triggers and Scripts forum for GUI code.

And, for future reference, every BJ could be optimized because BJs are either wrappers for Natives or Cumbersome functions that are inefficient.
There are some good BJs though:
- TriggerRegisterAnyUnitEventBJ
- GetCurrentCameraSetup
 
Level 7
Joined
Dec 3, 2006
Messages
339
I have some scripts that i'm wondering what to do to improve. I rather not post large portions of my map's or parts of my map's scripts here though. Do you have skype?
 
Level 31
Joined
Jul 10, 2007
Messages
6,306
Oh! I just noticed this thread :D
I ignored it for a while cause I wasn't getting any requests :S

@Switch33, post them in the pastebin ;)

@Nestharus, will do bro :) I'll try my best to increase Scrambler's efficiency (You'd need to develop a new algorithm though because it seems you've already optimized it well)
About BigInt, I see you've already optimized it :p
 
Status
Not open for further replies.
Top