Jump to content
Sign in to follow this  
Gudsawn

Code optimisation - loops

Recommended Posts

What would be the correct usage of compile preprocessFileLineNumbers when using loops? For example:

myScript.sqf

while {true} do {
    // Do something
    sleep 0.2;
};

Obviously this loop could be quite heavy on resources when run every 0.2 seconds, so to improve efficiency what would be more correct:

Method 1

myScript.sqf

// Do something

callMyScript.sqf

fnc_myScript = compile preprocessFileLineNumbers "myScript.sqf";

while {true} do {
    call fnc_myScript;
    sleep 0.2;
};

Method 2

myScript.sqf

while {true} do {
    // Do something
    sleep 0.2;
};

callMyScript.sqf

fnc_myScript = compile preprocessFileLineNumbers "myLoop.sqf";

call fnc_myScript;

Method 1 calls the function every 0.5 seconds on a loop.

Method 2 calls the the function only once, in which the loop within the script is run every 0.5 seconds.

Which is the correct method, and why?

Edited by GDSN

Share this post


Link to post
Share on other sites
you could wrap either approach into another function and:

BIS_fnc_codePerformance

it won't tell you the why... but should clarify which is faster.

Excellent, I will give this a try in the mean time.

Share this post


Link to post
Share on other sites

I think the idea with preprocessing is that if you were to call sumtin = [] execVM "aScript.sqf"; the file needs to be loaded from your hard disk(which as you know is REALLY SLOW) and then allocated a thread and all the overhead associated with it and some other stuff inside the file (possibly array allocation and such). If you preprocess it its basically reducing all that into a function and removing all that wasted time. In that way it would be now fast enough to call inside a time critical loop. And of course as its now a call you can't use sleep or waitUntil inside the file. So I think the answer is your original code:

while {true} do 
{
    // Do something
    sleep 0.2;
};  

is the fastest as it doesnt require you to jump from this location to another(thats what a call does)to find some code and then jump back. So it all depends on how efficient your (Do something) is. You could try different ways and check with the above posted profiling function to see which is the fastest. You would be surprised at how different your results can be with simple changes.... an example is I am currently rewriting someones mod for myself, and with all settings turned on my FPS drops to 15fps. after I rewrote the most important parts that has jumped back to 28-30 just by doing the same thing but in a different way.

Edited by Kunsa
how much wood could a woodchuck chuck if a woodchuck could chuck wood.

Share this post


Link to post
Share on other sites
...

Thanks Kunsa, very informative!

Edit: While on the topic, are preprocessFileLineNumbers and creating functions (my_fnc = {}) effectively the same?

Edited by GDSN

Share this post


Link to post
Share on other sites

call compile preprocessFile and execVM are identical up to the point of execution. While the former simply executes the code in context of the script the command was issued in, the latter has to create a new script ("thread"). This brings overhead and contributes to the so called script lag (scripts being interrupted to stop them from ruining FPS). That said, you should always try to use call compile preprocessFile over execVM unless you're in a context where this is not possible.

Share this post


Link to post
Share on other sites

What deadfast said. ExecVM is basically short for

[] spawn {_this call compile preProcessFileLineNumbers "script.sqf"}

Regarding your question there's no real answer, but having a while loop and then running that script makes the code easier to read. Spawning several threads does not necessarily mean that the script engine will be under heavy pressure.

What's more important is what you do in the loop/script

Share this post


Link to post
Share on other sites

hey guys im new to editing and i was wandering if anyone could help me with making usable items i have the 'sc items' mod and want to make usable bandages and repair kits mainly thanks

Share this post


Link to post
Share on other sites

Thank-you Deadfast and cuel for your answers. However, I'm not sure I fully understand this:

While the former simply executes the code in context of the script the command was issued in, the latter has to create a new script ("thread").

Could you expand on this a bit more. When calling a preprocessed file/function wouldn't it also need to create a new thread? Otherwise how would you call multiple functions at once/in parallel, unless they wait for each-other to finish?

I'm still not entirely sure I precisely know what it is about preprocessing that makes it more efficient. When a function is called ([] call fnc), and when a identical script is executed (execVM), they both still perform the same calculations - so what has changed?

Share this post


Link to post
Share on other sites
When calling a preprocessed file/function wouldn't it also need to create a new thread?

When calling no thread is created, when spawning yes. Using preprocessing does not commit you to either, it only means you save the string contents of preprocessed file to memory, ready to use at discretion.

I'm still not entirely sure I precisely know what it is about preprocessing that makes it more efficient. When a function is called ([] call fnc), and when a identical script is executed (execVM), they both still perform the same calculations - so what has changed?

You saved the string into memory, instead of fetching the sqf file each time you would (be it because you call the corresponding function or because you spawned it) and the overhead implied. execVM fetches the contents of the file each time it is called.

some generaly useful information in regards to code performance here.

Share this post


Link to post
Share on other sites
I'm still not entirely sure I precisely know what it is about preprocessing that makes it more efficient. When a function is called ([] call fnc), and when a identical script is executed (execVM), they both still perform the same calculations - so what has changed?

preProcessing means the string that is saved into memory is optimized (whitespaces, breaklines, comments are removed, since the script engine does not care about these)

The string/function can be re-used and does not have to be compiled again.

It makes no sense to do execVM on something that will be used often since the script file is basically preprocessed, saved into memory, run and then destroyed (since there's no string representing the function, at least that's how I'd imagine it to be)

Share this post


Link to post
Share on other sites

Ah I see, I understand now. Thanks again to both for your informative answers :)

Share this post


Link to post
Share on other sites

Please sign in to comment

You will be able to leave a comment after signing in



Sign In Now
Sign in to follow this  

×