Worldeater, thanks
Be careful when using exitWith
Yes, i know:
_res = ({
if( _x == _val )exitwith{ _x }; -1
} foreach [1,2,3,4,5])
in the case when _val is 4 then _res will be 4
in the case when _val is 987 then _res will be -1
I do not like
scopename,
breakout, they have awful syntax, and prefer to use in such cases,
try {throw} catch {}, although it is not semantic.
PS.
Generally speaking.
Boyer-Moore
Purely algorithmically, it executed almost as many operations just as would bruteforce.
All the stuff in the way we are working with the memory inside the interpreter.The whole trick is how it working with the memory inside the interpreter. And if BIS optimise work with memory it is a trick will cease to work. But is better they would add in sqf-language the join-command.
if you put the counter in the place where the concatenation, we can see that for an array of 30000 elements will be executed 30004 concatenation. but it works faster. magic?
This is a trick, not some sort of Big O algorithm
-------
edited, oh my english
-------
Continued.
Wow, I just learned about the existence of command diag_tickTime
So, now we can make more precise measurements:
#define inc(N) (call { N = N + 1; N })
#define arg(V) (_this select (V))
#define pushTo(array) call { array set [count array, _this] }
_testArray = [];
for "_i" from 1 to _this do {
"(" + (str _i) + ")" pushTo(_testArray);
};
_funcStupidJoin = { // bruteforce
private "_str";
_str = "";
{
_str = _str + _x;
inc(_counter);
} foreach arg(0);
_str;
};
_funcJoinString = {
private ["_list", "_glue", "_size", "_subsize", "_oversize", "_j"];
_list = arg(0);
_glue = arg(1);
if( count _list < 1 ) exitwith {""};
while { count _list > 1 } do {
_size = count _list / 2;
_subsize = floor _size;
_oversize = ceil _size;
_j = 0;
for "_i" from 0 to _subsize - 1 do {
inc(_counter);
_list set [_i, (_list select _j) + _glue + (_list select (_j+1))];
_j = _j + 2;
};
if( _subsize != _oversize )then {
inc(_counter);
_list set [_j/2, _list select _j];
};
_list resize _oversize;
};
_list select 0;
};
_text = [];
{
_func = call compile _x;
_arr = +_testArray;
_counter = 0;
_start = diag_tickTime;
[_arr, ", "] call _func;
format ["<t size='1.2'>%1</t><br />time: %2<br />count: %3", _x, diag_tickTime - _start, _counter] pushTo(_text)
} foreach ["_funcJoinString", "_funcStupidJoin"];
parseText ([_text, "<br />--------<br />"] call _funcJoinString) call {
hint _this;
_this
};
1000 call compile preprocessFile "testStringJoin.sqf"
Results:
100
_funcJoinString time: 0.00390625 count: 102
_funcStupidJoin time: 0 count: 100
10000
_funcJoinString time: 0.324219 count: 10005
_funcStupidJoin time: 1.39063 count: 10000
20000
_funcJoinString time: 0.878906 count: 20005
_funcStupidJoin time: 7.74219 count: 20000
30000
_funcJoinString time: 0.96875 count: 30004
_funcStupidJoin time: 11.2813 count: 30000
40000
_funcJoinString time: 1.42188 count: 40005
_funcStupidJoin time: 26.8477 count: 40000
50000
_funcJoinString time: 1.78516 count: 50006
_funcStupidJoin time: 44.9297 count: 50000
60000
_funcJoinString time: 1.97266 count: 60004
_funcStupidJoin time: 65.3164 count: 60000