• Listen to a special audio message from Bill Roper to the Hive Workshop community (Bill is a former Vice President of Blizzard Entertainment, Producer, Designer, Musician, Voice Actor) 🔗Click here to hear his message!
  • Read Evilhog's interview with Gregory Alper, the original composer of the music for WarCraft: Orcs & Humans 🔗Click here to read the full interview.

What does "GUI is slow" actually mean?

Status
Not open for further replies.
Level 5
Joined
May 20, 2008
Messages
138
I keep reading that GUI is slow because it uses BJ functions. What does this actually mean? I did a quick search of the forums and couldn't find any clear info. Will you notice severe performance issues in games with hundreds of GUI triggers or is it just "slow" in a programmer sense, i e GUI uses six lines of code for something JASS could have done in two?

Realistically wouldn't you just be executing a maximum of a couple hundred kilobytes of code at a time anyway, regardless if it is GUI or JASS? I thought any computer could handle that?
 
Level 6
Joined
Feb 5, 2012
Messages
1,685
The term slow is because.


Its kinda like this.

GUI Process

Write a GUI Function > Convert it to JASS Function > Execute the function during the game

JASS Process

Write a JASS Function > Execute the function during the game.


Why does the GUI Function needs to be converted?.. because warcraft engine needs to convert the Graphical User Interface to a Syntax to enable the engine to read it.
 
Level 5
Joined
May 20, 2008
Messages
138
But aren't the GUI triggers just a visual representation of the code that is saved in the map archive? Is the engine converting that code into ANOTHER code when you run the map? If so, why the hell did Blizzard make it that way? :p
 
Level 6
Joined
Feb 5, 2012
Messages
1,685
But aren't the GUI triggers just a visual representation of the code that is saved in the map archive? Is the engine converting that code into ANOTHER code when you run the map? If so, why the hell did Blizzard make it that way? :p

They need to make a GUI version of the JASS because..


1) Not all modders are syntax coding experts.

2) Noobs need a easy-to-understand way of coding (just like me when i start coding)

3) Its hard to understand JASS language for beginners (i dont even really understand hashtables)
 
Level 5
Joined
May 20, 2008
Messages
138
Either you are misunderstanding me, or I am misunderstanding you.
  • I get why GUI exists, yes.
  • As I understand it, GUI is a visual representation of JASS code to make it easier to understand for newbs like me.
  • Therefore, the JASS code already exists in the map file, I'm just looking at a visual representation of it in the GUI editor.
  • If this is true, then Warcraft shouldn't need to "convert" the GUI into JASS when you play the map, since the JASS code already exists.
Therefore, this doesn't make sense to me:

Its kinda like this.

GUI Process

Write a GUI Function > Convert it to JASS Function > Execute the function during the game

JASS Process

Write a JASS Function > Execute the function during the game.
 
Level 6
Joined
Feb 5, 2012
Messages
1,685
Either you are misunderstanding me, or I am misunderstanding you.
  • I get why GUI exists, yes.
  • As I understand it, GUI is a visual representation of JASS code to make it easier to understand for newbs like me.
  • Therefore, the JASS code already exists in the map file, I'm just looking at a visual representation of it in the GUI editor.
  • If this is true, then Warcraft shouldn't need to "convert" the GUI into JASS when you play the map, since the JASS code already exists.
Therefore, this doesn't make sense to me:

Ok you misunderstood me..

Warcraft engine cant read GUI so it needs to be converted in JASS.

It will be like eating a banana

Banana's skin makes it to look a banana but you can't eat the banana without removing its skin, right?..

So the warcraft engine removes the skin of the banana which is GUI and eats the inside which is the JASS.

For more clarrification take this for an example..

A = represents as noobs
B = represents as you
C = represents as are

in JASS it would be like this BCA. But if you can't understand it so it must be converted to GUI "you are noob".

There is already JASS. GUI "you are noob" is equivalent to "BCA". Since the engine can't read "you are noob" since its needs a syntax so it will use "BCA".
 
actually, I think it's not that which makes GUI slower.

let's take this ex :
  • Step 1
  • Events
  • Unit - A unit Dies
  • Conditions
  • (Triggering unit) Equal to Footman 0000 <gen>
  • Actions
  • Set tempPoint = (Random point in myRegion <gen>)
  • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
  • If - Conditions
  • (Life of (Triggering unit)) Greater than or equal to 10.00
  • Then - Actions
  • Unit - Order (Triggering unit) to Move To tempPoint
  • Else - Actions
  • Unit - Create 1 Footman for Player 1 (Red) at tempPoint facing 270.00 degrees
  • Custom script: call RemoveLocation( udg_tempPoint)
-->
JASS:
function Trig_Step_1_Conditions takes nothing returns boolean
    if ( not ( GetTriggerUnit() == gg_unit_hfoo_0000 ) ) then
        return false
    endif
    return true
endfunction

function Trig_Step_1_Func002C takes nothing returns boolean
    if ( not ( GetUnitStateSwap(UNIT_STATE_LIFE, GetTriggerUnit()) >= 10 ) ) then
        return false
    endif
    return true
endfunction

function Trig_Step_1_Actions takes nothing returns nothing
    set udg_tempPoint = GetRandomLocInRect(gg_rct_myRegion)
    if ( Trig_Step_1_Func002C() ) then
        call IssuePointOrderLocBJ( GetTriggerUnit(), "move", udg_tempPoint )
    else
        call CreateNUnitsAtLoc( 1, 'hfoo', Player(0), udg_tempPoint, 270.00 ) // notice player(0). in JASS player 1 red is actually Player(0)
    endif
    call RemoveLocation( udg_tempPoint)
endfunction

//===========================================================================
function InitTrig_Step_1 takes nothing returns nothing
    set gg_trg_Step_1 = CreateTrigger(  )
    call TriggerRegisterAnyUnitEventBJ( gg_trg_Step_1, EVENT_PLAYER_UNIT_DEATH )
    call TriggerAddCondition( gg_trg_Step_1, Condition( function Trig_Step_1_Conditions ) )
    call TriggerAddAction( gg_trg_Step_1, function Trig_Step_1_Actions )
endfunction

Is slower than :

JASS:
function Trig_Step_1_Actions takes nothing returns nothing
    local real x = GetRandomReal(GetRectMinX( udg_region), GetRectMaxX( udg_region))
    local real y = GetRandomReal(GetRectMinY( udg_region), GetRectMaxY( udg_region))
    local unit u = GetTriggerUnit()
    if GetUnitState( u, UNIT_STATE_LIFE) >= 10 then 
        call IssuePointOrder( u, "move", x, y)
    else
        call CreateUnit( Player(0), 'hfoo', x, y, 270)
    endif
    set u = null
endfunction

function Trig_Step_1_Conditions takes nothing returns boolean
    if GetTriggerUnit() == gg_unit_hfoo_0000 then
        call Trig_Step_1_Actions() // this is how you call a function you have made.
    endif
    return false
endfunction

//===========================================================================
function InitTrig_Step_1 takes nothing returns nothing
    local trigger t = CreateTrigger() 
    call TriggerRegisterAnyUnitEventBJ( t, EVENT_PLAYER_UNIT_DEATH )
    call TriggerAddCondition( t, Condition( function Trig_Step_1_Conditions))
    set t = null
endfunction

why?
  1. GUI Uses Locations which is slower than Jass "Real Hooking" method
  2. GUI Create additional thread for actions and conditions
  3. GUI's BJ function actually are longer than actual natives for Jass [check JNGP's Jass List and see for yourself], where Jass only create a function with 1 or 2 lines but GUI BJ functions usually create 3 or 4 lines.
there are some I might miss, but you can get the idea I hope.
 
Level 6
Joined
Feb 5, 2012
Messages
1,685
actually, I think it's not that which makes GUI slower.

let's take this ex :
  • Step 1
  • Events
  • Unit - A unit Dies
  • Conditions
  • (Triggering unit) Equal to Footman 0000 <gen>
  • Actions
  • Set tempPoint = (Random point in myRegion <gen>)
  • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
  • If - Conditions
  • (Life of (Triggering unit)) Greater than or equal to 10.00
  • Then - Actions
  • Unit - Order (Triggering unit) to Move To tempPoint
  • Else - Actions
  • Unit - Create 1 Footman for Player 1 (Red) at tempPoint facing 270.00 degrees
  • Custom script: call RemoveLocation( udg_tempPoint)
-->
JASS:
function Trig_Step_1_Conditions takes nothing returns boolean
    if ( not ( GetTriggerUnit() == gg_unit_hfoo_0000 ) ) then
        return false
    endif
    return true
endfunction

function Trig_Step_1_Func002C takes nothing returns boolean
    if ( not ( GetUnitStateSwap(UNIT_STATE_LIFE, GetTriggerUnit()) >= 10 ) ) then
        return false
    endif
    return true
endfunction

function Trig_Step_1_Actions takes nothing returns nothing
    set udg_tempPoint = GetRandomLocInRect(gg_rct_myRegion)
    if ( Trig_Step_1_Func002C() ) then
        call IssuePointOrderLocBJ( GetTriggerUnit(), "move", udg_tempPoint )
    else
        call CreateNUnitsAtLoc( 1, 'hfoo', Player(0), udg_tempPoint, 270.00 ) // notice player(0). in JASS player 1 red is actually Player(0)
    endif
    call RemoveLocation( udg_tempPoint)
endfunction

//===========================================================================
function InitTrig_Step_1 takes nothing returns nothing
    set gg_trg_Step_1 = CreateTrigger(  )
    call TriggerRegisterAnyUnitEventBJ( gg_trg_Step_1, EVENT_PLAYER_UNIT_DEATH )
    call TriggerAddCondition( gg_trg_Step_1, Condition( function Trig_Step_1_Conditions ) )
    call TriggerAddAction( gg_trg_Step_1, function Trig_Step_1_Actions )
endfunction

Is slower than :

JASS:
function Trig_Step_1_Actions takes nothing returns nothing
    local real x = GetRandomReal(GetRectMinX( udg_region), GetRectMaxX( udg_region))
    local real y = GetRandomReal(GetRectMinY( udg_region), GetRectMaxY( udg_region))
    local unit u = GetTriggerUnit()
    if GetUnitState( u, UNIT_STATE_LIFE) >= 10 then 
        call IssuePointOrder( u, "move", x, y)
    else
        call CreateUnit( Player(0), 'hfoo', x, y, 270)
    endif
    set u = null
endfunction

function Trig_Step_1_Conditions takes nothing returns boolean
    if GetTriggerUnit() == gg_unit_hfoo_0000 then
        call Trig_Step_1_Actions() // this is how you call a function you have made.
    endif
    return false
endfunction

//===========================================================================
function InitTrig_Step_1 takes nothing returns nothing
    local trigger t = CreateTrigger() 
    call TriggerRegisterAnyUnitEventBJ( t, EVENT_PLAYER_UNIT_DEATH )
    call TriggerAddCondition( t, Condition( function Trig_Step_1_Conditions))
    set t = null
endfunction

why?
  1. GUI Uses Locations which is slower than Jass "Real Hooking" method
  2. GUI Create additional thread for actions and conditions
  3. GUI's BJ function actually are longer than actual natives for Jass [check JNGP's Jass List and see for yourself], where Jass only create a function with 1 or 2 lines but GUI BJ functions usually create 3 or 4 lines.
there are some I might miss, but you can get the idea I hope.

This a good example
 
Level 16
Joined
Mar 27, 2011
Messages
1,349
Write a GUI Function > Convert it to JASS Function > Execute the function during the game

JASS Process

Write a JASS Function > Execute the function during the game.

According to you, GUI is converted to Jass during the game. Then it is executed. And THIS is why GUI is slower according to you. You have not provided any other reason why it is slower.

What Marshmellows is asking and now I am to. Is why on Earth is GUI converted to Jass during the INGAME? Terrible design flaw to me. Why wouldn't it be converted upon saving the map. Or possibly during loading of the map to reduce INGAME lag of conversion?

Edit: Ok Daffa's explanation makes sense :)
 
Level 6
Joined
Feb 5, 2012
Messages
1,685
According to you, GUI is converted to Jass during the game. Then it is executed. And THIS is why GUI is slower according to you. You have not provided any other reason why it is slower.

What Marshmellows is asking and now I am to. Is why on Earth is GUI converted to Jass during the INGAME? Terrible design flaw to me. Why wouldn't it be converted upon saving the map. Or possibly during loading of the map to reduce INGAME lag of conversion?

Edit: Ok Daffa's explanation makes sense :)

Well my mistake. I think they convert it during the loading of the game.
 
Honestly, I believe GUI is already treated as JASS by the game itself [if not, the game will lag like shit everytime a new event runs, OR game will have very long loading time], it's slower mostly because of how GUI uses stuffs, such as Location [opposed to Jass "Real Hooking"], BJs [where Jass uses natives which is considerably faster], and many other flaws. But in-game, most of them can't be noticed with naked eyes [I believe], unless on some cases.
 
@neo_sluf: Just to clear things up, they convert it each time you save the map. When you play the map, the GUI form of the triggers are useless (since they were already converted and put in the war3map.j), so they just take up space. You can actually delete the wtg file (triggers) and it will still be playable in Warcraft III (but not openable in the editor), and that is what a lot of optimizers/protectors do. :)

@OP: Now, the rates in which GUI is slower can really vary from code to code. In general, BJ's are ever-so-slightly slower than calling natives directly. However, I don't think that is the real problem behind GUI. Saving a few nanoseconds won't help anyone. And in the case of GUI vs JASS, it is usually a difference of some nanoseconds, or perhaps a few milliseconds for long code.

You can code really crappy GUI and it will run poorly. You can also run really crappy JASS, and it can run poorly too. The real problem behind GUI (in my eyes) is that you don't have full control over what happens internally. By choosing to use GUI functions (BJ functions), you will often suffer from Blizzard's reference leaks and whatnot. For example, PolledWait() leaks a reference. SmartCameraPanBJ() will desync. GetCurrentCameraSetup() will also leak a reference. A lot of group functions will leak references too. A lot of these are minor, but as they build up they can lead to efficiency problems.

Why does this happen? Well, the reference leak is generally referred to as a "bug". Blizzard probably didn't even know about it when they wrote their functions, which is why a lot of the functions still leak. By choosing JASS, you get absolute control over the natives and functions so you can prevent those leaks.

All in all, GUI's faults come from how Blizzard designed it. IMO, the biggest issue are the internal leaks that you have no control over. However, a lot of this can be trivial unless you deal with a lot of periodic triggers or if your map has a stress-testing-esque environment. Most computers can handle the faults, to a decent extent.

----
As for me, the main speed difference is just for editing (typing). :) I type JASS a lot faster than I can make a GUI trigger. I just don't like looking through the windows anymore. There are a lot of other reasons to use JASS, too, such as having more control/easier access to the other natives, e.g. trackables.
 
Level 5
Joined
May 20, 2008
Messages
138
Honestly, I believe GUI is already treated as JASS by the game itself [if not, the game will lag like shit everytime a new event runs, OR game will have very long loading time], it's slower mostly because of how GUI uses stuffs, such as Location [opposed to Jass "Real Hooking"], BJs [where Jass uses natives which is considerably faster], and many other flaws. But in-game, most of them can't be noticed with naked eyes [I believe], unless on some cases.
@neo_sluf: Just to clear things up, they convert it each time you save the map. When you play the map, the GUI form of the triggers are useless (since they were already converted and put in the war3map.j), so they just take up space. You can actually delete the wtg file (triggers) and it will still be playable in Warcraft III (but not openable in the editor), and that is what a lot of optimizers/protectors do. :)

@OP: Now, the rates in which GUI is slower can really vary from code to code. In general, BJ's are ever-so-slightly slower than calling natives directly. However, I don't think that is the real problem behind GUI. Saving a few nanoseconds won't help anyone. And in the case of GUI vs JASS, it is usually a difference of some nanoseconds, or perhaps a few milliseconds for long code.

You can code really crappy GUI and it will run poorly. You can also run really crappy JASS, and it can run poorly too. The real problem behind GUI (in my eyes) is that you don't have full control over what happens internally. By choosing to use GUI functions (BJ functions), you will often suffer from Blizzard's reference leaks and whatnot. For example, PolledWait() leaks a reference. SmartCameraPanBJ() will desync. GetCurrentCameraSetup() will also leak a reference. A lot of group functions will leak references too. A lot of these are minor, but as they build up they can lead to efficiency problems.

Why does this happen? Well, the reference leak is generally referred to as a "bug". Blizzard probably didn't even know about it when they wrote their functions, which is why a lot of the functions still leak. By choosing JASS, you get absolute control over the natives and functions so you can prevent those leaks.

All in all, GUI's faults come from how Blizzard designed it. IMO, the biggest issue are the internal leaks that you have no control over. However, a lot of this can be trivial unless you deal with a lot of periodic triggers or if your map has a stress-testing-esque environment. Most computers can handle the faults, to a decent extent.

----
As for me, the main speed difference is just for editing (typing). :) I type JASS a lot faster than I can make a GUI trigger. I just don't like looking through the windows anymore. There are a lot of other reasons to use JASS, too, such as having more control/easier access to the other natives, e.g. trackables.

Ok thanks, this answers my questions. I wonder why Blizzard didn't realize (or care) that their functions leak, I mean surely they should be quite advanced programmers over there?

What does it mean that a function leaks references, by the way? Are there corresponding functions that work the same way, but do NOT leak references, in JASS?

Is there some way I can read up what GUI functions create these internal leaks? Then I could take a look at my triggers and see if there are any that I should rewrite in JASS (I just need to finally understand the logic of JASS first lol). I know how to clean the usual unit group, point, etc. leaks with custom scripts.
 
Ok thanks, this answers my questions. I wonder why Blizzard didn't realize (or care) that their functions leak, I mean surely they should be quite advanced programmers over there?
I presume Blizzard don't want to fix an old game like Warcraft 3.
Also, if they aren't advanced programmers, they can't make Warcraft 3 along with it's Editor like what we have today.
 
Level 5
Joined
May 20, 2008
Messages
138
I presume Blizzard don't want to fix an old game like Warcraft 3.
Also, if they aren't advanced programmers, they can't make Warcraft 3 along with it's Editor like what we have today.

You misunderstand me. I wonder why they didn't realize/fix it when they MADE the game back in 2000. They are advanced programmers so surely they should have seen the problems?
 
You misunderstand me. I wonder why they didn't realize/fix it when they MADE the game back in 2000. They are advanced programmers so surely they should have seen the problems?

Yeah, back then, but possibly because they are also working on other games as well, Also, it's maybe because they don't care about the flaw.
 
Level 22
Joined
Sep 24, 2005
Messages
4,821
Ok thanks, this answers my questions. I wonder why Blizzard didn't realize (or care) that their functions leak, I mean surely they should be quite advanced programmers over there?
That question should be addressed directly to Blizzard, we can only speculate why.
What does it mean that a function leaks references, by the way? Are there corresponding functions that work the same way, but do NOT leak references, in JASS?
First of all, GUI triggers are interfaces(think of it as a person translating for you) of jass functions, the purpose of the trigger interface is to allow ease of use and suggest what actions (identification of functions) a map modder could use.

Functions are pre-defined actions that a computer (in this case, application software) will perform, functions do not leak.

Variables are storage for data, variables with data that is not referenced (Forgotten) uses memory and becomes useless, and because it is not referenced you cannot return the said memory to the system. They call it a memory leak.

Is there some way I can read up what GUI functions create these internal leaks? Then I could take a look at my triggers and see if there are any that I should rewrite in JASS (I just need to finally understand the logic of JASS first lol). I know how to clean the usual unit group, point, etc. leaks with custom scripts.

There is a tutorial link on top of the page, start looking there.
 
You misunderstand me. I wonder why they didn't realize/fix it when they MADE the game back in 2000. They are advanced programmers so surely they should have seen the problems?

As chobibo said, we can only speculate. My perspective: the leak isn't that prominent--you probably won't notice it until you are dealing with several thousands of reference leaks (possibly tens of thousands). The main way to notice the issue is by looking at the behavior of the handle ID's--the handle ID's are not recycled when there is a reference leak.

Basically, when an object in memory is recycled in Warcraft III, the engine first checks if it has any local variables still pointing to it before recycling the handle ID. If there are some, it will not recycle the handle ID (it will clear the memory held by the object, though). This causes a leak in memory because the handle ID never gets recycled (there is no way to reduce the reference count since that local variable's scope has already ended).

Blizzard didn't have a native/function to view the handle ID of an object back then, so the leak probably went unnoticed for a while. When H2I was discovered (gets the handle ID of an object through exploiting the return bug), this leak became much more apparent since we could look at the handle ID's of objects. However, either Blizzard still never realized it or they just didn't care. After the major bugs with editing were fixed, Blizzard began to focus more on melee in terms of patching. They have fixed some leaks in the past (unit leak and GroupEnum leak), but never the reference leak.

Is there some way I can read up what GUI functions create these internal leaks? Then I could take a look at my triggers and see if there are any that I should rewrite in JASS (I just need to finally understand the logic of JASS first lol). I know how to clean the usual unit group, point, etc. leaks with custom scripts.

I should really make a list. Maybe I will make one later and post it in the lab or something. :) But as of now, there is no such list.
 
Level 5
Joined
May 20, 2008
Messages
138
Hm, I only have like 700 GUI triggers, let's hope my map will still work lol

I should really make a list. Maybe I will make one later and post it in the lab or something. :) But as of now, there is no such list.
That would be sweet.

Thanks for the explaining guys.
 
Level 4
Joined
Aug 18, 2013
Messages
71
I'll Save you OP!
Okay
GUI is Converted to JASS then converted to Machine Code/Game Code (Used by your Computer as Binary)

This part is not important because this really doesn't affect game play as only what is Underlined happened during the game, everything else was done in the compiler and World Editor.

A WC3 Map file is incredibly "Dumb'ed Down", the file only contains very basic information, otherwise the game would have to compile Jass/Gui before every game, this would be very very slow. So the "Dumbed Down" information is already converted to Machine/Game Code in the Map File. When you load a game, you only are loading assets/art/Machine Code/units (Which are converted to the same code as Machine, Fun huh?)

Our Editors convert it back to JASS/GUI when we open the map.

So Why is GUI considered slower?

Lets look more into it:

GUI is a Representation of JASS. JASS and GUI in terms of functionality are exactly the same thing, just seen from two different POVs. So Saying GUI is converted straight into JASS is technically not true either. GUI and JASS are the same thing, just represented differently. What makes it slower though is GUI is 'Static' in the sense that you can't manipulate what Blizzard has set the GUI functions to represent.
For Example: When a trigger is created, it is done quite inefficiently compared to what we can do in JASS

The Below is GUI Converted to JASS
  • TestTrigger
    • Events
      • Time - Elapsed game time is 5.00 seconds
    • Conditions
      • (Difficulty level) Equal to Normal
    • Actions
      • -------- This is my example trigger, --------
      • Game - Display to (All players) the text: The game difficulty...
      • Melee Game - Use melee time of day (for all players)
      • Neutral Building - Add 99999 gold to No unit
Jass Conversion
JASS:
function Trig_TestTrigger_Conditions takes nothing returns boolean
    if ( not ( GetGameDifficulty() == MAP_DIFFICULTY_NORMAL ) ) then
        return false
    endif
    return true
endfunction

function Trig_TestTrigger_Actions takes nothing returns nothing
    // This is my example trigger,
    call DisplayTextToForce( GetPlayersAll(), "TRIGSTR_2681" )
    call MeleeStartingVisibility(  )
    call AddResourceAmountBJ( 99999, null )
endfunction

//===========================================================================
function InitTrig_TestTrigger takes nothing returns nothing
    set gg_trg_TestTrigger = CreateTrigger(  )
    call TriggerRegisterTimerEventSingle( gg_trg_TestTrigger, 5 )
    call TriggerAddCondition( gg_trg_TestTrigger, Condition( function Trig_TestTrigger_Conditions ) )
    call TriggerAddAction( gg_trg_TestTrigger, function Trig_TestTrigger_Actions )
endfunction

These two thing are identical, not aesthetically but functionality wise(The Editor will fix the Aesthetics). The Compiler will read both of these things equally fast. The Real Problem arises when "Round-A-Bout Ways" are used to achieve simple tasks (Blizzard really dropped the ball)

In this code the condition

JASS:
function Trig_TestTrigger_Conditions takes nothing returns boolean
    if ( not ( GetGameDifficulty() == MAP_DIFFICULTY_NORMAL ) ) then
        return false
    endif
    return true
endfunction

requires nearly twice as long as

JASS:
function Trig_TestTrigger_Conditions takes nothing returns boolean
    return( GetGameDifficulty() == MAP_DIFFICULTY_NORMAL )
endfunction
this is fixed gui code


This may not seem that detrimental, but you may use any number of conditions that will all be this difficult and congested. And Thats only one Trigger, Imagine what the computer may endure when you have nearly 100 triggers, or 1000. That is literally 1000 instances of twice, thrice, or more, the time required than what is necessary.

Also mentioned by fellow members, GUI Leaks handles. This leads to lag, but JASS can be checked and double checked to clean all leaks.

Other Examples of GUI Code that is inefficient

Trigger/GUI
  • Set var = (Strength of Unit (Exclude bonuses))
Jass Converted GUI
JASS:
set var = GetHeroStatBJ( bj_HEROSTAT_STR,Unit,false)
only to call this function right after to finish setting the Variable
JASS:
function GetHeroStatBJ takes integer whichStat, unit whichHero, boolean includeBonuses returns integer
    if (whichStat == bj_HEROSTAT_STR) then
        return GetHeroStr(whichHero, includeBonuses)
    elseif (whichStat == bj_HEROSTAT_AGI) then
        return GetHeroAgi(whichHero, includeBonuses)
    elseif (whichStat == bj_HEROSTAT_INT) then
        return GetHeroInt(whichHero, includeBonuses)
    else
        // Unrecognized hero stat - return 0
        return 0
    endif
endfunction

When Any of These Three should have been used

JASS:
set var = GetHeroStr(Unit,  true or false)
-
JASS:
set var = GetHeroAgi(Unit, true or false)
-
JASS:
set var = GetHeroInt(Unit,  true or false)


There many instances if these happening and none of them are efficient, but this is what the GUI represents.

JASS is completely more efficient assuming the user knows what they are doing (Obviously Blizzard does not) ;)

I apologize for opening an old thread, but I had to help this guy, I feel no one got through to him;
and in my defense, the thread was already close to the top; EDITED: of my search -- Whoops.
 
Last edited:
Level 14
Joined
Jun 27, 2008
Messages
1,325
Aww sooo colorfull. Too bad i disagree on the content...


GUI is Converted to JASS then converted to Machine Code/Game Code (Used by your Computer as Binary)

This part is not important because this really doesn't affect game play as only what is Underlined happened during the game, everything else was done in the compiler and World Editor.

A WC3 Map file is incredibly "Dumb'ed Down", the file only contains very basic information, otherwise the game would have to compile Jass/Gui before every game, this would be very very slow. So the "Dumbed Down" information is already converted to Machine/Game Code in the Map File. When you load a game, you only are loading assets/art/Machine Code/units (Which are converted to the same code as Machine, Fun huh?)

Its does not get converted to machine code, its interpreted.

Our Editors convert it back to JASS/GUI when we open the map.

No. The user-made triggers (Jass and GUI) are stored in the map archive along with the map script "war3map.j" which contains the converted user-made triggers + some code generated by the editor.
When you open the map in the editor nothing gets "converted back", the editor just opens the respective files.

So Why is GUI considered slower?

Lets look more into it:

GUI is a Representation of JASS. JASS and GUI in terms of functionality are exactly the same thing, just seen from two different POVs. So Saying GUI is converted straight into JASS is technically not true either. GUI and JASS are the same thing, just represented differently. What makes it slower though is GUI is 'Static' in the sense that you can't manipulate what Blizzard has set the GUI functions to represent.
For Example: When a trigger is created, it is done quite inefficiently compared to what we can do in JASS

The Below is GUI Converted to JASS
  • TestTrigger
    • Events
      • Time - Elapsed game time is 5.00 seconds
    • Conditions
      • (Difficulty level) Equal to Normal
    • Actions
      • -------- This is my example trigger, --------
      • Game - Display to (All players) the text: The game difficulty...
      • Melee Game - Use melee time of day (for all players)
      • Neutral Building - Add 99999 gold to No unit
Jass Conversion
JASS:
function Trig_TestTrigger_Conditions takes nothing returns boolean
    if ( not ( GetGameDifficulty() == MAP_DIFFICULTY_NORMAL ) ) then
        return false
    endif
    return true
endfunction

function Trig_TestTrigger_Actions takes nothing returns nothing
    // This is my example trigger,
    call DisplayTextToForce( GetPlayersAll(), "TRIGSTR_2681" )
    call MeleeStartingVisibility(  )
    call AddResourceAmountBJ( 99999, null )
endfunction

//===========================================================================
function InitTrig_TestTrigger takes nothing returns nothing
    set gg_trg_TestTrigger = CreateTrigger(  )
    call TriggerRegisterTimerEventSingle( gg_trg_TestTrigger, 5 )
    call TriggerAddCondition( gg_trg_TestTrigger, Condition( function Trig_TestTrigger_Conditions ) )
    call TriggerAddAction( gg_trg_TestTrigger, function Trig_TestTrigger_Actions )
endfunction

These two thing are identical, not aesthetically but functionality wise(The Editor will fix the Aesthetics). The Compiler will read both of these things equally fast. The Real Problem arises when "Round-A-Bout Ways" are used to achieve simple tasks (Blizzard really dropped the ball)

In this code the condition

JASS:
function Trig_TestTrigger_Conditions takes nothing returns boolean
    if ( not ( GetGameDifficulty() == MAP_DIFFICULTY_NORMAL ) ) then
        return false
    endif
    return true
endfunction

requires nearly twice as long as

JASS:
function Trig_TestTrigger_Conditions takes nothing returns boolean
    return( GetGameDifficulty() == MAP_DIFFICULTY_NORMAL )
endfunction
this is fixed gui code


This may not seem that detrimental, but you may use any number of conditions that will all be this difficult and congested. And Thats only one Trigger, Imagine what the computer may endure when you have nearly 100 triggers, or 1000. That is literally 1000 instances of twice, thrice, or more, the time required than what is necessary.

Also mentioned by fellow members, GUI Leaks handles. This leads to lag, but JASS can be checked and double checked to clean all leaks.

Other Examples of GUI Code that is inefficient

Trigger/GUI
  • Set var = (Strength of Unit (Exclude bonuses))
Jass Converted GUI
JASS:
set var = GetHeroStatBJ( bj_HEROSTAT_STR,Unit,false)
only to call this function right after to finish setting the Variable
JASS:
function GetHeroStatBJ takes integer whichStat, unit whichHero, boolean includeBonuses returns integer
    if (whichStat == bj_HEROSTAT_STR) then
        return GetHeroStr(whichHero, includeBonuses)
    elseif (whichStat == bj_HEROSTAT_AGI) then
        return GetHeroAgi(whichHero, includeBonuses)
    elseif (whichStat == bj_HEROSTAT_INT) then
        return GetHeroInt(whichHero, includeBonuses)
    else
        // Unrecognized hero stat - return 0
        return 0
    endif
endfunction

When Any of These Three should have been used

JASS:
set var = GetHeroStr(Unit,  true or false)
-
JASS:
set var = GetHeroAgi(Unit, true or false)
-
JASS:
set var = GetHeroInt(Unit,  true or false)


There many instances if these happening and none of them are efficient, but this is what the GUI represents.

JASS is completely more efficient assuming the user knows what they are doing (Obviously Blizzard does not) ;)

I apologize for opening an old thread, but I had to help this guy, I feel no one got through to him;
and in my defense, the thread was already close to the top; EDITED: of my search -- Whoops.

Technically most of this stuff is true, but when you call GUI slow because it sometimes adds an unnecessary amount of "if" to the code you should also mention that the performance difference is so incredibly small that this is NOT relevant to most triggers.
In both GUI and Jass you can create very fast and very slow triggers, the language doesnt change much. What sometimes makes a difference is that GUI lacks functionality which sometimes forces you to use suboptimal workarounds, a good example are timers (GUI timers are very limited since you can only react to them via a trigger object).
 
Level 21
Joined
Mar 27, 2012
Messages
3,232
The main points that I'd bring out are mostly already mentioned.

Main reasons why GUI runs slower:
1. Pure JASS has more functionality than GUI; For whatever reason, not all JASS natives were added to GUI. This means that when you only work in GUI, you might have to use huge workarounds in some cases.
2. Performance degradation from some actions(those that leak references or perhaps even values).
The reason why blizzard didn't fix this(and many other things) is that it didn't bother them. Blizzard maps have leaky triggers, but it doesn't matter, because blizzard didn't use lots of high-rate loops together with leaky things.
GUI(or JASS) for this purpose, was not originally meant to be as expansive as it is now. Blizzard itself only used it for simple triggering, not massive systems like we like to create now.

Why writing JASS is faster than making GUI triggers:
1. You can copy-paste all text, not just separate actions.
2. Typing is often faster than using menus
3. You can use functions, which reduces the time spent on writing the same parts of code all over again. Furthermore, if a function is buggy, you only have to fix it in one place(usually).
 
Level 4
Joined
Aug 18, 2013
Messages
71
lack of insight. your computer is still converting it to 0's and 1's (Machine code) voila. this is hardware/software related. I don't care. it doesn't matter. thanks
 
Level 14
Joined
Jun 27, 2008
Messages
1,325
Ok... here is how a damn interpreted language works.. lol


First, it goes through the lexical analysis to get the tokens
Next, it goes through the parser to get the tree
After this, it is translated into bytecode, which is then executed
The actions to take are based on the deployer, which is a giant switch statement

That's exactly what the damn wikipedia page site that you linked states too >.>


So please don't scream bs and then link a site that states exactly what I just said, it's funny ; P
 
Level 22
Joined
Sep 24, 2005
Messages
4,821
The time difference between yours and muzzle post is 1 minute. He must have been still typing his reply when you were posting yours.
 
Status
Not open for further replies.
Top