Code Optimisation: Difference between revisions

From Bohemia Interactive Community
Jump to navigation Jump to search
Line 50: Line 50:
==Loops==
==Loops==


These first two loop types are identical in speed (+/- 10%), and are more than 2x as fast the proceeding two loop types.
These first two loop types are identical in speed (+/- 10%), and are more than 3x as fast the proceeding two loop types.


*for "_y" from 0 to (count [0,0,0,0] - 1) step 1 do { ... };
*for "_y" from 0 to ( ... ) step # do { ... };
*{ ... } foreach [0,0,0,0];
*{ ... } foreach [ ... ];


Where as these two loops are much slower, and for maximum performance, avoided.
Where as these two loops are much slower, and for maximum performance, avoided.


*_y=0; while {_y = _y + 1; _y < count [0,0,0,0]} do { ... };
*while { expression } do { code };
*for [{_y=0},{_y<(count [0,0,0,0])},{_y=_y+1}] do { ... }
*for [{ ... },{ ... },{ ... }] do { ... }


Waituntil can be used when you want something to only run once per frame, which can be handy for limiting scripts that may be resource heavy.
Waituntil can be used when you want something to only run once per frame, which can be handy for limiting scripts that may be resource heavy.

Revision as of 11:58, 27 April 2010

Make it work.

No need to worry about making it work at light speed if it doesn't even do what it is supposed to. Focus on getting a working product first.

Make it fast.

Optimisation is everything when running lots of instances, with low delays. However, there is such thing as premature optimisation. Also, avoid excessive cleverness.

"Excessive cleverness is doing something in a really clever way when actually you could have done it in a much more straightforward but slightly less optimal manner. You've probably seen examples of people who construct amazing chains of macros (in C) or bizarre overloading patterns (in C++) which work fine but which you look at an go "wtf"? EC is a variation of premature-optimisation. It's also an act of hubris - programmers doing things because they want to show how clever they are rather than getting the job done." - sbsmac

Make it pretty.

Documentation, readability, and all that jazz. Clean code is good code.

Written it twice? Put it in a function

Pre-compilation by the game engine can save up 20x the amount of time processing, even if the initial time is slightly lengthened. If you've written it twice, or if there is a kind of loop consistently being compiled (perhaps a script run by execVM), make it into a function (FUNCVAR =compile preprocessfilelinenumbers "filename.sqf").

Adding elements to an array

Removing elements from an array

When FIFO removing elements from an array, the set removal method works best, even if it makes a copy of the new array.

ARRAYX set [0, objnull]; ARRAYX = ARRAYX - [objnull];

Getting position

If your feeling self-conscious and want an AGL solution (ie identical to that of getPos): _pos=getposATL player; if(surfaceIsWater _pos)then{_pos = getposASL player};

It is still 25% faster than its getPos twin.

CreateVehicle Array

http://community.bistudio.com/wiki/createVehicle

Does not take 3D positions, 2D only, and is 500x slower than its younger brother:

http://community.bistudio.com/wiki/createVehicle_array

You know what to do. (Incase you don't, USE CREATEVEHICLE ARRAY!!!)

10,000 Iterations Limit in Loops

Doesn't exist in scheduled environments, only in non - scheduled (only where the 0.3ms delay does not exist).

Loops

These first two loop types are identical in speed (+/- 10%), and are more than 3x as fast the proceeding two loop types.

  • for "_y" from 0 to ( ... ) step # do { ... };
  • { ... } foreach [ ... ];

Where as these two loops are much slower, and for maximum performance, avoided.

  • while { expression } do { code };
  • for [{ ... },{ ... },{ ... }] do { ... }

Waituntil can be used when you want something to only run once per frame, which can be handy for limiting scripts that may be resource heavy.

  • waituntil {expression};

Avoid O(n^2)!!

Commonly you may set up foreach foreach's. 'For' example:

  • { { ... } foreach [0,0,0]; } foreach [0,0,0];

This example is of the order (n^2) (3^2 = 9 iterations). For each element you add to this, it will increase the processing exponentially. Which can lead to poor performance in snap functions.

Avoiding the 0.3ms delay

Many times you may want to avoid the 0.3 ms delay (not 3ms!), and there a few tricks around how to do it...

  • Triggers are inside what we call the 'non-scheduled' environment.
  • All pre-init code executions are without scheduling.
  • FSM conditions are without scheduling
  • Event handlers (on units and in GUI) are without scheduling

Measuring Velocity Scalar

Sure we can just use Pythagorean theorem to calculate the magnitude from a velocity vector, but a command native to the engine runs much faster (over 10x faster) than the math.

  • VECTOR distance [0,0,0]

Works for 2D vectors as well.