Jump to content
Blitzen88

“Lazy Evaluations” - If and Select

Recommended Posts

I’ve been looking at some script optimization and I’m a little confused about IF/Select statements and “lazy evaluation.”

 

From my understanding, if the condition is written correctly, an If statement is more efficient if it is properly written with the correct syntax:

 

If ( {Condition1} && {Condition2} && {Condition3} ) then { nothing };

 

My understanding is, if Condition1 is false, then the statement will NOT check Condition2 and Condition3 – the check essentially ends when Condition1 returns false.

 

However, how does that work with a Select command and OR? For instance:


_AllVehicles = _AllVehicles select { (!canMove _x) || (!alive driver _x) || ( (count crew _x) == 0) || ( (!isNull gunner _x) && (!alive gunner _x) ) || ( (!isNull gunner _x) && (!canFire _x) ) };

 

Will the script continue to evaluate the other conditions even if the vehicle cannot move?  Do I need to change my brackets to accomplish that?

 

Just wanted to check.

Share this post


Link to post
Share on other sites

First of all:

If (  Condition1 && {Condition2} && {Condition3} ) then { something }; // first part of condition is not a code

 

_AllVehicles select { !canMove _x or {!alive driver _x} or {crew _x isEqualTo []} or { !isNull gunner _x && !alive gunner _x} or {!isNull gunner _x && !canFire _x} };

Not sure what you want to do with that but this line is same as yours.

Note: Lazy eval can be counter-performant if your condition returns often false at the end. Furthermore, the choice of the sequence can impact on optimization. You can test your condition in real time, from debug console performance timer icon. Shift two parts of condition and see the timer.

 

 

  • Like 2

Share this post


Link to post
Share on other sites

You can check it by yourself by calling conditions with systemchat or hint commands, for example:

Your_condition_1 = 
	{
		systemchat "cond 1";
		
		false;
	};
	
Your_condition_2 = 
	{
		systemchat "cond 2";
		
		false;
	};
	
Your_condition_3 = 
	{
		systemchat "cond 3";
		
		false;
	};
	
if (call Your_condition_1 && call Your_condition_2 && call Your_condition_3) then {};

/*Then delete it and replace by:*/

_Your_false_units = units group player select {call Your_condition_1 && call Your_condition_2 && call Your_condition_3};

/*Then run the following and see the difference:*/ 

if (call Your_condition_1 && {call Your_condition_2 && {call Your_condition_3}}) then {};
_Your_false_units = units group player select {call Your_condition_1 && {call Your_condition_2 && {call Your_condition_3}}};

If you see 3 systemchats on your screen, it means that your code evaluates 3 conditions. 
If your see 1 systemchat, it means, that only first condition was evaluated. 

Share this post


Link to post
Share on other sites
1 hour ago, pierremgi said:

 

Note: Lazy eval can be counter-performant if your condition returns often false at the end. Furthermore, the choice of the sequence can impact on optimization. You can test your condition in real time, from debug console performance timer icon. Shift two parts of condition and see the timer.

 

 

This is what I’m trying to figure out. I have certain conditions that need to be evaluated at the start of the IF/Select command but I need to make sure I have the syntax right. 

Share this post


Link to post
Share on other sites
7 hours ago, Ibragim A said:

You can check it by yourself by calling conditions with systemchat or hint commands, for example:


Your_condition_1 = 
	{
		systemchat "cond 1";
		
		false;
	};
	
Your_condition_2 = 
	{
		systemchat "cond 2";
		
		false;
	};
	
Your_condition_3 = 
	{
		systemchat "cond 3";
		
		false;
	};
	
if (call Your_condition_1 && call Your_condition_2 && call Your_condition_3) then {};

/*Then delete it and replace by:*/

_Your_false_units = units group player select {call Your_condition_1 && call Your_condition_2 && call Your_condition_3};

/*Then run the following and see the difference:*/ 

if (call Your_condition_1 && {call Your_condition_2 && {call Your_condition_3}}) then {};
_Your_false_units = units group player select {call Your_condition_1 && {call Your_condition_2 && {call Your_condition_3}}};

If you see 3 systemchats on your screen, it means that your code evaluates 3 conditions. 
If your see 1 systemchat, it means, that only first condition was evaluated. 

I was able to take this and figure it out from there.  Thank you for helping me out!

Share this post


Link to post
Share on other sites
13 hours ago, Blitzen88 said:

This is what I’m trying to figure out. I have certain conditions that need to be evaluated at the start of the IF/Select command but I need to make sure I have the syntax right. 

You can use the debug console performance timer (little squared icon above watch:)

 

or intuitive method: if you want a condition about OPFOR tanks  for a scenario with  100 BLUFOR vehicles with 3 tanks vs 20 OPFOR vehicles with 5 tanks , you can write:

vehicles select {side _x == EAST && _x isKindOf "tank"} // 120 checks for each part of conditions (bad)

or

vehicles select {side _x == EAST && {_x iskindOf "tank"}}  //120 checks but 20 checks only for the 2nd part (is this a tank?) (there are only 20 OPFOR vehicles)
or

vehicles select {_x isKindOf "tank" && {side _x == EAST}} // 120 checks but 8 checks only for the 2nd part (is this tank OPFOR?) (there are only 8 tanks)

 

to be exhaustive, you should also compare the speed for checking  a vehicle isKindOf "tank" vs the  vehicle's side is EAST ....

Intuitive method may be counter-performing.

I recommend the performance timer of the debug console, especially for complex filter on heavy configs (with multiple DLCs/mods)

 

Share this post


Link to post
Share on other sites
4 hours ago, pierremgi said:

You can use the debug console performance timer (little squared icon above watch:)


I recommend the performance timer of the debug console, especially for complex filter on heavy configs (with multiple DLCs/mods)

 

I started playing around with the performance tool yesterday but I noticed it didnt take input variables and didnt account for sleeps..?

Share this post


Link to post
Share on other sites
5 hours ago, Blitzen88 said:

I started playing around with the performance tool yesterday but I noticed it didnt take input variables and didnt account for sleeps..?

Variables must be defined, not coming from nowhere. And evaluation can't be in scheduled scope. You run 10,000 times unscheduled code (or less for heavy code).

Share this post


Link to post
Share on other sites
53 minutes ago, pierremgi said:

Variables must be defined, not coming from nowhere. And evaluation can't be in scheduled scope. You run 10,000 times unscheduled code (or less for heavy code).

Is the 10,000 iterations built into the tool? How can I get an evaluation for a single run?

 

I couldnt find any info about it on the wiki

Share this post


Link to post
Share on other sites
53 minutes ago, Blitzen88 said:

Is the 10,000 iterations built into the tool? How can I get an evaluation for a single run?

 

I couldnt find any info about it on the wiki

evaluation built-in is an average on 10,000 runs of the code and that's fine! testing a  millisecond or micro second code on one run is not reliable!

If you want more explanation, try to search for performance tools. Some hints:

https://community.bistudio.com/wiki/Mission_Optimisation

https://steamcommunity.com/sharedfiles/filedetails/?id=1731305438

https://community.bistudio.com/wiki/Arma_3:_Performance_Optimisation

 

And you have a specific branch of Arma: https://community.bistudio.com/wiki/Arma_3:_Diagnostics_Exe

 

 

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

×