igneous01 19 Posted February 14, 2017 I have some functions that are used to generate / obtain a subset from a collection, with a predicate as an argument (a form of Inversion of Control), but the problem is that the call generates a lot of overhead. fnc_generate = { params["_size", "_initV", "_pred"]; private _array = []; private _it = _initV; for [{_i = 0}, {_i < _size}, {_i = _i + 1}] do { _array pushback (call _pred); }; _array; }; fnc_subset = { params["_array", "_pred"]; private _collection = []; { if (_x call _pred) then { _collection pushback _x; }; } foreach _array; _collection; }; I'm comparing doing the following: // Manual way BIGARRAY = []; for [{_i=0}, {_i < 10000}, {_i = _i + 1}] do { BIGARRAY pushback _i; }; // 45 ms avg BIGARRAY = []; BIGARRAY = [10000, 0, {_it = _it + 1; _it;}] call fnc_generate; // 68 ms avg // manual way SUBSET = []; { if (_x > 10) then { SUBSET pushback _x; }; } forEach BIGARRAY; // 47 ms avg SUBSET = []; SUBSET = [BIGARRAY, {_this > 10;}] call fnc_subset; // 69 ms avg Adding call makes the code ~28% slower, and this starts to get noticeable if you are doing things like this often/with larger sets of data. Is there a way to inline the predicate so that it just replaces (call _pred) with the predicate code the user passed in? Macros have a way of doing this sort of replace, but the problem is you cant use preprocess commands on a function, only on a filepath. Share this post Link to post Share on other sites
serena 150 Posted February 14, 2017 At least you can resize array after creation to avoid reallocations and remove excess _initV variable: fnc_generate = { params["_size", "_it", "_pred"]; private _array = []; _array resize _size; for [{_i = 0}, {_i < _size}, {_i = _i + 1}] do { _array set [_i, call _pred]}; _array }; Fixed set command, thanks killzone_kid 1 Share this post Link to post Share on other sites
serena 150 Posted February 14, 2017 Your fnc_subset can be easily "inlined" with: private _result = _array select {_x call _pred}; 2 Share this post Link to post Share on other sites
killzone_kid 1326 Posted February 14, 2017 37 minutes ago, serena said: _set not possible 1 Share this post Link to post Share on other sites
igneous01 19 Posted February 14, 2017 1 hour ago, serena said: Your fnc_subset can be easily "inlined" with: private _result = _array select {_x call _pred}; that's a new one, I'm glad they added in select with expression, means I don't need to create a subset function to do this. How fast is this method? Share this post Link to post Share on other sites