BJ vs. No-BJ (Get your mind out of the gutter)

Status
Not open for further replies.

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:
Code:
function FooBJ takes unit A, integer B returns boolean
    return Foo(B, A)
endfunction
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):
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. :cool:
 

corvusHaunt

New Member
Reaction score
96
You used BJ functions in the "non-bj" test function...


This is a big mess that can be easily avoided by using natives directly, and not making the game do the math by using a calculator and doing it yourself.

Code:
function CreateTextTagLocBJ takes string s, location loc, real zOffset, real size, real red, real green, real blue, real transparency returns texttag
    set bj_lastCreatedTextTag = CreateTextTag()
   [COLOR=Navy] call SetTextTagTextBJ(bj_lastCreatedTextTag, s, size)[/COLOR]
   [COLOR=Green] call SetTextTagPosBJ(bj_lastCreatedTextTag, loc, zOffset)[/COLOR]
   [COLOR=Red] call SetTextTagColorBJ(bj_lastCreatedTextTag, red, green, blue, transparency)[/COLOR]

    return bj_lastCreatedTextTag
endfunction

Code:
[COLOR=Navy]function SetTextTagTextBJ takes texttag tt, string s, real size returns nothing
    local real textHeight = TextTagSize2Height(size)

    call SetTextTagText(tt, s, textHeight)
endfunction[/COLOR]

Code:
[COLOR=Navy]function TextTagSize2Height takes real size returns real
    return size * 0.023 / 10
endfunction[/COLOR]

Code:
[COLOR=Green]function SetTextTagPosBJ takes texttag tt, location loc, real zOffset returns nothing
    call SetTextTagPos(tt, GetLocationX(loc), GetLocationY(loc), zOffset)
endfunction[/COLOR]

Code:
[COLOR=Red]function SetTextTagColorBJ takes texttag tt, real red, real green, real blue, real transparency returns nothing
    call SetTextTagColor(tt, PercentTo255(red), PercentTo255(green), PercentTo255(blue), PercentTo255(100.0-transparency))
endfunction[/COLOR]

Code:
[COLOR=Red]function PercentTo255 takes real percentage returns integer
    return PercentToInt(percentage, 255)
endfunction[/COLOR]

Code:
[COLOR=Red]function PercentToInt takes real percentage, integer max returns integer
    local integer result = R2I(percentage * I2R(max) * 0.01)

    if (result < 0) then
        set result = 0
    elseif (result > max) then
        set result = max
    endif

    return result
endfunction[/COLOR]



Here is a GUI example of a very common type of trigger:

Code:
Slide
    Events
        Time - Every 0.01 seconds of game time
    Conditions
    Actions
        Player Group - Pick every player in (All players) and do (Actions)
            Loop - Actions
                Unit Group - Pick every unit in (Units in (Playable map area) matching ((Owner of (Picked Unit))) Equal to (Picked Player))) and do (Actions)
                    Loop - Actions
                        Unit - Move (Picked unit) instantly to ((Position of (Picked unit)) offset by (Percentage life of (Picked unit)) towards (Facing of (Picked unit)) degrees), facing (Facing of (Picked unit)) degrees)

This leaks tons and takes a good bit of computing power, every hundredth of a second. I would lay it out and show you all the useless BJ functions it uses, but you'd have to scroll down quite a ways to see the next reply...
 

Luth

Lex Luthor!
Reaction score
41
You used BJ functions in the "non-bj" test function...

I think you missed the point. Its a controlled experiment, if you've heard that term before. The rest of the trigger stays the same, so as not to skew results, but the control factors changed; in this case, switching two natives for the two non-natives in the inner loop.


And, also, I think you missed the results. There is not any "big mess" to take care of. At best, in theory, natives are imperceivably faster than their non-native BJ wrappers, not having to do, say, an extra function call or a multiplication. On average, and in reality, they're just as fast, and will not hinder game performance in any way, and as you skillfully showed, can make things a lot easier to deal with.


Did you even read the post, or just the title? :nuts:
 

corvusHaunt

New Member
Reaction score
96
I didn't mean visible mess. I'm not going to kill you if you use BJ functions, because they aren't generally that bad.

But, if you think even more realistically, you'll see that in-game, you can have dozens of triggers running at once. This isn't bad at first, but with the example trigger I showed, even if you remove the leaks, you can leak performance and build up the needed computing power. People seem to forget that computer memory is a limited thing, and that even harmless sounding things like some math functions can slow down performance. Replacing these performance slowing BJ's with more effecient code can really ease the job for your computer. Don't forget either that some people run WC3 on computers that have to work their cpu out just to not lag with a few units on screen.
 
L

Lordbevan

Guest
Nice work, but i must said it could be tough to find a trigger where native is so much faster than non-natives.
 

SFilip

Gone but not forgotten
Reaction score
634
> So little that you'd never notice it.
exactly. just like a memory leak - it takes around 16-32 bytes which is so little compared to the memory standards today.
yet when you have many...yeah, they wont be "little and cute" anymore.

also some BJs are different...they call other BJs, sometimes more than one making it even slower.

and afaik vex's optimizer can fix some BJs, but not all. i always like to do it manually ;)
 

Luth

Lex Luthor!
Reaction score
41
But, if you think even more realistically, you'll see that in-game, you can have dozens of triggers running at once.
So devise a more rigid test, if you dont like 10,000 BJ calls in under half a second. I think thats more than any game will likely to have, dozens of triggers or not. If you have otherwise, I think non-native functions may not be your real problem. :cool: It's a simple task to modify and run that test in multiple parallel triggers, and test your hypothesis.

just like a memory leak - it takes around 16-32 bytes which is so little compared to the memory standards today.
yet when you have many...yeah, they wont be "little and cute" anymore. also some BJs are different...they call other BJs, sometimes more than one making it even slower.
Invalid comparison. Memory leaks are cumulative, function calls arent. You might use an extra 10,000 function calls per second, as I did in my test, but it STILL didnt make any difference. By those meager findings, if you were doing 1,000,000 or more extra function calls per second, you might notice; but only if you were watching the numbers, certainly not if you were simply watching framerate. If you'll recall, I readily admit that it does perform extra work, but the conclusion was that the processor is not being over taxed to the point of disruption, even in extreme cases such as the test provided.

And, again, dont take my word for it, test it for yourself. Take the biggest, baddest BJ function you know of, and run a stress test. There's not much to discuss, the results speak for themselves. Thats the wonderful part of it all. We all have opinions, but now we have actual evidence, which makes opinions moot.



Here's another one
To further illustrate, and to test the BJ's calling other BJ's point, I modified the map (attached below) to include an additional three layers of wrapper to the BJ functions. Thats right, now each inner-loop BJ call now has a total of four layers of function wrapper before it reaches API. :cool:
Code:
function wrapper_3 takes nothing returns nothing
    call UnitAddAbilityBJ( 'Absk', gg_unit_hpea_0000 )
endfunction

function wrapper_2 takes nothing returns nothing
    call wrapper_3()
endfunction

function wrapper_1 takes nothing returns nothing
    call wrapper_2()
endfunction


function unwrapper_3 takes nothing returns nothing
    call UnitRemoveAbilityBJ( 'Absk', gg_unit_hpea_0000 )
endfunction

function unwrapper_2 takes nothing returns nothing
    call unwrapper_3()
endfunction

function unwrapper_1 takes nothing returns nothing
    call unwrapper_2()
endfunction
And what did we find? In a short test, here were the results:
Code:
BJ      Non-BJ
12.851  12.863
12.844  12.840
12.833  12.832
12.830  12.820

BJ Avg:      12.8395
Non-BJ Avg:  12.8388
Again, even with an additional six extra function calls per inner loop, the BJ and non-BJ tests are running in the same time. No doubt that if more than four tests were performed, the numbers would be even more unbelievably closer than they are.

This needs to be partially explained, because it doesnt make immidiate sense. We have proven that it is doing more work, so it should take longer, right? Yes, and no. The processor can do X amount of calculations per clock-tick, where X is a number larger than you've ever counted. ;) The increased number of instruction calls just isnt enough to warrent substantial (if any) additional clock-ticks, so they run in, as shown, the same amount of time.

I love it when the numbers speak for themselves. :cool:
 

emjlr3

Change can be a good thing
Reaction score
395
but here is the real kicker

if your going to code in JASS, why write in bjs, instead of natives? they are slower and nomrlally longer to write...just makes no sense...sorta like this thread

we know the diff is small, but when you have 50 at a time, all firing, all game long, a bunch here, a bunch there, it makes a difference, now instead of jsut one of these tests, run 50 at a time, and see what happens....

this thread is sorta like saying....I could buy the #1 rated tv, for less of a hassle, but I'll buy the #5 rated, which also costs more, just cuz I feel like it....
 

Vexorian

Why no custom sig?
Reaction score
187
Hey genius, your test is using a wait, hell it is NEVER going to be accurate AT ALL.

If you want to know how slow a function call is, well I am gonna tell you. A wrapper function takes as much time as the half of what a gamecache native takes. We all agree that gamecache is slow, then take a guess on what is the worth of unnecesary function calls and how the simple step of getting rid of them could improve your execution. Check out the difference between the first test and the second one : http://www.wc3campaigns.net/showthread.php?t=87184 .

Another thing:

call UnitAddAbilityBJ('Aloc',u)

They are just incredibly lame, like this one, the name says Unit before Ability yet the argument has the ability first then the unit.

There isn't much sense in using JASS if you are gonna write code that is as lame as the one generated by GUI.
 

Luth

Lex Luthor!
Reaction score
41
Hehe, you silly people get so worked up about your "natives"... :cool:

emjlr3 said:
but here is the real kicker

if your going to code in JASS, why write in bjs, instead of natives? they are slower and nomrlally longer to write...just makes no sense...sorta like this thread

we know the diff is small, but when you have 50 at a time, all firing, all game long, a bunch here, a bunch there, it makes a difference, now instead of jsut one of these tests, run 50 at a time, and see what happens....

this thread is sorta like saying....I could buy the #1 rated tv, for less of a hassle, but I'll buy the #5 rated, which also costs more, just cuz I feel like it....

Why not? If the fancy suits you, why not use non-natives? They are, so far, not measureably slower, and many simple functions can be clicked up faster in the GUI than written by hand, especially for beginners (who seem to get reemed the most, barring this thread, poor gits).

Also, I think thats a silly request, 50 triggers all firing at the same time, each doing tens of thousands of commands per second. I doubt you, in your best of days, couldnt write a map utilizing that much processing power. Pretty sure I couldnt come up with a valid use. Regardless, I did it anyway. (I was curious.) I had 50 triggers created, and fired at the same time, each running the same loop tests as before, 10,000 iterations.
Code:
BJ test finished in 37.4 sec, 37.1 sec
Non-BJ test finished in 37.3 sec, 37.3 sec
Also, to please, reducing the iteractions to 3,000 and removing the wait statements, both the BJ and Non-BJ tests repeatedly scored, as above, within a .3 sec range, best to worst.

Again, I could run this test a few dozen times, but already I see what has been shown before, and as I expected. Even with dozens of concurrent triggers, and tens of thousands of commands per second, the times remain the same. You dont have to believe me, I'm not trying to belittle you non-non-native users (which is why I dont understand when you types get silly and belittle poor kids on the forums), but every test so far, every variation so far, the results are the same.

Vex: "handlevars vs tables" really doesnt actually mean anything to me. And, actually, I dont know enough about the gamecache implementation to be able to judge it. Fortunately, though, most BJs dont deal with such things, and this isnt attempting to prove that All of One is better than All of Another; I picked a pair of BJs out of JC113 at random to stress-test. Also, if my tests were as inaccurate as you implied, then I should be getting a wider range of resultant data, which I'm not. Still though, as stated above, I tested without any waits, and the results were (concidentally, if nothing else) exactly the same. :shades:


C'mon, think about it... what is a wrapper call? Its a jump, and maybe a couple of stack pushes and pops. (Maybe in other applications, it could even be allocation/deallocation, which would probably give us some difference to measure.) If we had processors measured in the 1,000s of operations per second, we might be in trouble, but we're not running this on our TI-83, are we?
Is it slower? Indeed! Is it measurably slower? No, not so far. Would it be faster to not use any function calls, and write all code inline? Sure, but thats impractical. Has anyone reading this thread wasted more time than all the BJs in the world combined? Certainly.

If you've got a test that shows how bad the average wrapper hurts a map, please show me. Prove me wrong, and then you (the generic 'you') can be justified in picking on people who use BJs. (Thats what prompted this, anyway... month after month, seeing people make fun of people using bj funcs.) Until then, since there is no proof that an extra function call will hurt your map in any way, shape, or form, even when tested in the extremes, maybe all you (the generic 'you') insult-happy 1337 d00ds can sit happy and proud with yourself, knowing that your code is as native as it can get, and not push that Reply button to let everyone else know how much disgust you have with others that dont follow your shining example.
 
L

Lordbevan

Guest
I am interested to know about the speed in GUI functions vs direct JASS. E.g.
Simple conditions in GUI requries one function call, while in JASS its just a direct comparision. Anyone got some test results to show?
 

corvusHaunt

New Member
Reaction score
96
I don't care about BJ's for the most part, it's just my preference to do the work myself and make my code "neat". The thing I do care about is the leaks that some of these BJ's create. People have to watch out for these; no, they aren't going to crash the game by themselves, but if you do have alot of leaks - especially in functions that you run constantly - then the effects of that will show.
 

emjlr3

Change can be a good thing
Reaction score
395
luth you still make no sense, your only good argument is that slow typers may be able to GUI - convert faster, but that is stupid, if you are coding in JASS Craft, it has all the functions there for you, and i am pretty sure double clicking the function is faster then finding it in GUI then converting and reranging your variables and such

so again, I ask you....why use bjs at all? it still makes absolutly no sense

you don't need a test to prove 1 is better then 2 in this situation, especially when 1 is easier to type and makes more sense written out, and has no leaks
 
P

pattern

Guest
If I understand what he's trying to prove it's not that there's not a differance, but that the differance is neglible (sp?) so if either way you go about it, using bj's won't slow your game to a halt like many apparently think/advocate? Correct me if I'm wrong here cause I really don't know much about the subject, but I think I at least understand the point... :)
 

Daelin

Kelani Mage
Reaction score
172
I can't believe you just tried to trash what Vexorian said. Learn to listen other people's opinion before starting to spread your poison. Let's make this clear. Some non-natives are really STUPID. I don't see the point of doing something like this:

Code:
function UnitAddAbilityBJ takes integer abilityId, unit whichUnit returns boolean
    return UnitAddAbility(whichUnit, abilityId)
endfunction

Why would you use a function that just calls a native doing the exact same thing with inversed parameters? I'll give you the answer: because you're lazy, and because you just want to be cool and do it different just for the sake of saying "hah, I did it the unconventional way". If you want to call yourself a good JASS coder, you will never do that. It is one of the unwritten laws (or is it written) of programming: never add unecessary calculations, no matter how unsignificant for the efficiency they are.

Here's the thing. Every bit of slow code becomes very important at a certain point. Did you ever tried to make a huge map playable by up to 12 players, filled with custom abilities which overlap one another and are cast at unknown times, and at unknown frequency? Not to mention that it is played on the map. The way we use timers can slow things up even on perfect coding. It is best to try to avoid that slowness any other ways. I tell ya, you could use all the efficiency you can get.

Oh, and another thing, some blizzard functions actually LEAK. Don't come to tell me that "the leaking stuff doesn't exist" because it was proven through TESTS just like the one you ran that there are problems from not nulling stuff. You want an example?

Code:
function CountLivingPlayerUnitsOfTypeId takes integer unitId, player whichPlayer returns integer
    local group g
    local integer matchedCount

    set g = CreateGroup()
    set bj_livingPlayerUnitsTypeId = unitId
    call GroupEnumUnitsOfPlayer(g, whichPlayer, filterLivingPlayerUnitsOfTypeId)
    set matchedCount = CountUnitsInGroup(g)
    call DestroyGroup(g)

    return matchedCount
endfunction

Groups g and matchedCount leak. Surprisingly as it is, they do! Ask any mediocre JASS programmer who has decent knowledge about memory leaks and he will confirm you this.

And jesus christ, using waits when running such a test... Might I ask how you calculated the time?

~Daelin
 

Effane

Save/Load Code Tutorial
Reaction score
51
Its a natural phenomenon for people to skew the results to their opinion. This goes both ways and in any "scientific" test its a major issue. Data can always be interpreted and even the data sets you decide on from the beginning can be biased. The only true way to get a 100% test is to cover almost all the possible combinations using the most basic testing procedures. And even then I am sure some will show no positive result, while others will show positive results. People will then try to interpret those results into their own bias, and you will be back at square one. This may be one of the biggest issues in the scientific community right now as the problems tackled get bigger and bigger.
 
C

Capt Griffen

Guest
Without a native pack addition, nothing in game can test execution time. Thus, your results merely show you have no clue what the heck you are talking about.

Natives are clearer, more efficient, and more flexible. End of story.
 

SFilip

Gone but not forgotten
Reaction score
634
> Natives are clearer, more efficient, and more flexible. End of story.
QFT

> I can't believe you just tried to trash what Vexorian said.
> Some non-natives are really STUPID.
> never add unecessary calculations, no matter how unsignificant for the efficiency they are.
again QFT

though you confused me here...
> Groups g and matchedCount leak.
matchedCount is an integer, afaik they don't leak...or am i wrong?

BJs are slower and they do affect your thread limit. most of them are easy to "fix" so why do you even bother running a test like this? besides if you really do use jass (not just convert and add a few locals) then don't you think its easier to type UnitAddItem instead of UnitAddItemSwapped for instance?
 

Daelin

Kelani Mage
Reaction score
172
SFilip said:
> Groups g and matchedCount leak.
matchedCount is an integer, afaik they don't leak...or am i wrong?
Well... no. I got overrun a little. Ok, matchedCount does not but g definitely does!


SFilip said:
BJs do affect your thread limit.
Damn good argument, might I add. If the speed stuff was not good, this sure is!

~Daelin
 

Luth

Lex Luthor!
Reaction score
41
emjlr3 said:
luth you still make no sense, your only good argument is that slow typers may be able to GUI - convert faster, but that is stupid, if you are coding in JASS Craft, it has all the functions there for you, and i am pretty sure double clicking the function is faster then finding it in GUI then converting and reranging your variables and such

so again, I ask you....why use bjs at all? it still makes absolutly no sense

you don't need a test to prove 1 is better then 2 in this situation, especially when 1 is easier to type and makes more sense written out, and has no leaks

JassCraft isnt stable on my laptop for some reason. It has a nasty habit of crashing, and losing my work. I use it for function reference, at best. I still use WE for triggering out of necessity. Its a slight bit more stable.

Why use bjs? Why not? I memorized them faster than the natives, just in that I've seen them more, so they're more easily called from memory. They're just as easy to read (unless the letters "BJ" make you giggle uncontrolably, in which case, non-natives arent really your problem), and just as fast, as measured in clock ticks (not instruction calls, obviously). The point is NOT that non-natives are better, but rather, in practical application, just as good, and those who reem others on the board (thank goodness not you, big E, nor Vex here) should really have an understanding of how bad BJs are (or arent). For most, it seems, its a pride issue. "MY script has NO non-natives. Yours has three, ergo, you are a horrible scripter, and you should stop posting." An over-exaggeration to illustrate my point. Surely you've seen this just as much as I have.

Pattern: Precisely right. I would wager that any generic non-native script will run on-par with any native-only script. Even in extremes, such as 50 triggers running 1000s of operations per second, as demonstrated, didnt show any noticable difference. Are natives better? Sure. Is a $1,000,000,000.01 more money than $1,000,000,000.00? Sure. The difference, in general, is negligable.

Daelin: You're a prime example of what I'm advocating against. You're ignoring the imperical data, and speaking from pride. :( I dont think I'm "cool" for using non-natives. If I had them all memorized, I'd use them. But with a little bit of thought, and even testing, I've proven to any that can read that the difference is not.
Here's the thing. Every bit of slow code becomes very important at a certain point. Did you ever tried to make a huge map playable by up to 12 players, filled with custom abilities which overlap one another and are cast at unknown times, and at unknown frequency? Not to mention that it is played on the map. The way we use timers can slow things up even on perfect coding. It is best to try to avoid that slowness any other ways. I tell ya, you could use all the efficiency you can get.
Yes, I have. And even under worse case scenarios, provided by Emj, the extra function wrapper did not affect overall performance at all. Not one bit.
never add unecessary calculations, no matter how unsignificant for the efficiency they are.
I cant but shake my head in dissapointment. I dont know you, nor your abilities, but thats the silliest thing I've read all week. For example, functions are unnecessary operations. Why call MAX(A,B) when you can do the calculations inline, thus saving the function call? Why use, taken from your own map,
Code:
constant function ManaPulse_SpellRaw takes nothing returns integer
    return 'A001' //main ability rawcode
endfunction
when simply putting 'A001' everywhere would do sufficiently? You're using one function call when zero would do! Heaven forbid! But I'm not a novice, and I dont believe any of what I just stated, true as it may be. Its for ease of use, readability, and future modification. But the point is, even you, more-perfect-jasser-than-thou-Daelin, justifications aside, are guilty of the same thing you accuse me: Using one extra function call.
some blizzard functions actually LEAK. ... Groups g and matchedCount leak.
If proven to be bad or damaging code, then dont use them. Duh. You're not an idiot, and I dont treat you like one; at least have the same courtesy of others. (For the record, though, integers like matchedCount dont leak. They're pushed onto the stack, then popped when the calling function regains control of the process. Ask any mediocre JASS programmer who has decent knowledge about memory leaks and he will confirm you this. ) And, out of curiousity, do you know the implimentation of TriggerSleepAction at the code level? (Do you know code?) Having written similiar systems before, I have a pretty good understanding, and judge its accuracy therein. Also, as you may have skipped over, eliminating the Wait statements changed the results by none. If anything, it brought the results even closer together. (A good suggestion though it was, I think it had the opposite effect that it was implied it would.) :cool:

BJs are slower and they do affect your thread limit.
Quite true. They are one wrapper call slower, in general. This isnt an arguable point; it was conceeded in the first post. The point is that you are unable to measure how much longer it takes, because the speed of operations is beyond you. The thread limit is a valid arguement, and perhaps the only one I've seen yet, as it applies to all wrapper functions, leaking or leakless. Though, on how many occasions have you actually reached thread limit? I've made eight or more maps now, and have only reached thread limit when trying to, such as in the demos shown here. Never in any production map have I even come close, BJs or no. I feel like I'm repeating myself, but if you have an ability trigger that is reaching the thread execution limit, then more than likely, saving a dozen wrapper calls isnt going to do a whole lot for you. Its akin to using a $1 off coupon when buying a new home.

As for "trashing what Vex said", I neither attempted nor did any such thing. I dont know enough about the IO operations of the gamecache implementation, nor the "table system" that he tests, in order to speak intelligently on the subject; a restraint which I would be pleased to see others practice. (oh snap, corvus. ps: thx for deleting that post.) The data he showed seemed evident, but not understanding what he was testing, it made no sense to me, so I cannot discuss it. His implications that a Sleep() call was skewing the results were valid, so I did yet another test of 50 simultaneous triggers running thousands of operations without any Wait statements, and the results were in the same range, if not closer, than those with Wait statements. A valid challenge, and the results, again, speak for themselves. I think, perhaps, many do not actually understand how many of these things are implemented at a code-or-lower level.

Having replied to these as I read them, I see now that you, Daelin, have taken back what you said about integer leaks, but it does show evidence that you were speaking out of pride or emotion, rather than thought and logic. It is, undoubtedly, this same irrationality that causes you, and others, to berate those who use non-native functions when its beyond reproach that they do not measurably damage their triggers in any fashion.


Am I against using natives? Not at all! Over time, I'm sure I'll memorize enough of them that I wont be using BJs, except when they're convenient or make sense. Do I think its wrong to belittle those who do, insisting that they're "not real JASS scripters"? Indeed, of course, certainly. The end script runs just as fast, just as well, just as leak-free (barring those few BJs that dont clean up after themselves), are as easily readable and modifiable, and produce the exact same output; criticizing the use of a wrapper seems a last desperate attempt to discourage and humiliate someone when all valid criticisms have proven fruitless. This, above all else, is my point.
 
Status
Not open for further replies.
General chit-chat
Help Users
  • No one is chatting at the moment.
  • Ghan Ghan:
    Howdy
  • Ghan Ghan:
    Still lurking
    +3
  • The Helper The Helper:
    I am great and it is fantastic to see you my friend!
    +1
  • The Helper The Helper:
    If you are new to the site please check out the Recipe and Food Forum https://www.thehelper.net/forums/recipes-and-food.220/
  • Monovertex Monovertex:
    How come you're so into recipes lately? Never saw this much interest in this topic in the old days of TH.net
  • Monovertex Monovertex:
    Hmm, how do I change my signature?
  • tom_mai78101 tom_mai78101:
    Signatures can be edit in your account profile. As for the old stuffs, I'm thinking it's because Blizzard is now under Microsoft, and because of Microsoft Xbox going the way it is, it's dreadful.
  • The Helper The Helper:
    I am not big on the recipes I am just promoting them - I use the site as a practice place promoting stuff
    +2
  • Monovertex Monovertex:
    @tom_mai78101 I must be blind. If I go on my profile I don't see any area to edit the signature; If I go to account details (settings) I don't see any signature area either.
  • The Helper The Helper:
    You can get there if you click the bell icon (alerts) and choose preferences from the bottom, signature will be in the menu on the left there https://www.thehelper.net/account/preferences
  • The Helper The Helper:
    I think I need to split the Sci/Tech news forum into 2 one for Science and one for Tech but I am hating all the moving of posts I would have to do
  • The Helper The Helper:
    What is up Old Mountain Shadow?
  • The Helper The Helper:
    Happy Thursday!
    +1
  • Varine Varine:
    Crazy how much 3d printing has come in the last few years. Sad that it's not as easily modifiable though
  • Varine Varine:
    I bought an Ender 3 during the pandemic and tinkered with it all the time. Just bought a Sovol, not as easy. I'm trying to make it use a different nozzle because I have a fuck ton of Volcanos, and they use what is basically a modified volcano that is just a smidge longer, and almost every part on this thing needs to be redone to make it work
  • Varine Varine:
    Luckily I have a 3d printer for that, I guess. But it's ridiculous. The regular volcanos are 21mm, these Sovol versions are about 23.5mm
  • Varine Varine:
    So, 2.5mm longer. But the thing that measures the bed is about 1.5mm above the nozzle, so if I swap it with a volcano then I'm 1mm behind it. So cool, new bracket to swap that, but THEN the fan shroud to direct air at the part is ALSO going to be .5mm to low, and so I need to redo that, but by doing that it is a little bit off where it should be blowing and it's throwing it at the heating block instead of the part, and fuck man
  • Varine Varine:
    I didn't realize they designed this entire thing to NOT be modded. I would have just got a fucking Bambu if I knew that, the whole point was I could fuck with this. And no one else makes shit for Sovol so I have to go through them, and they have... interesting pricing models. So I have a new extruder altogether that I'm taking apart and going to just design a whole new one to use my nozzles. Dumb design.
  • Varine Varine:
    Can't just buy a new heatblock, you need to get a whole hotend - so block, heater cartridge, thermistor, heatbreak, and nozzle. And they put this fucking paste in there so I can't take the thermistor or cartridge out with any ease, that's 30 dollars. Or you can get the whole extrudor with the direct driver AND that heatblock for like 50, but you still can't get any of it to come apart
  • Varine Varine:
    Partsbuilt has individual parts I found but they're expensive. I think I can get bits swapped around and make this work with generic shit though
  • Ghan Ghan:
    Heard Houston got hit pretty bad by storms last night. Hope all is well with TH.
  • The Helper The Helper:
    Power back on finally - all is good here no damage
    +2
  • V-SNES V-SNES:
    Happy Friday!
    +1

      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