Don't worry, I spent a long time trying to make a decent benchmark myself.
time definitely doesn't work in the way you'd expect it to.
The interpreter is totally aware that it are working with arrays and is, in fact, using the most optimised implementation for what you ask it to do (computers are very literal, as you know):
_array = _array + [_element];
Is asking "Please create a new array by concatenating _array and [_element], then assign that new array to _array". The interpreter doesn't look at the whole line when parsing,
Think of it differently:
_newArray = _array + [_element];
which obviously can't be optimised to a push, since the interpreter cannot alter _array, or
_referenceToArray = _array;
// Later...
_array = _referenceToArray + [_element];
Which could potentially become a push, but it is that much harder for the parser to catch (well, the parser can't catch that one, so you'd need to perform optimisation passes over the generated parse-tree, something that would take longer to do in an interpreter than time it would save; in a compiler, the time spent matters a lot less).
For interest, the parser would break down:
_array = _array + [_element];
into (well, simplified, but)
1. Create a new array (call it _
tmp1).
2. Put _element into _
tmp1.
3. Create a new array (call it _
tmp2) and copy all values of _
array and _
tmp1 into it.
4. Set _array to reference _
tmp25. The original _
array and _
tmp1 are no longer referenced, so can be cleaned up by the garbage collector.
I am explaining this in detail since some people might be interested in how interpreters work. You absolutely don't need to understand all this as a normal user of SQF
I'll repeat again, that
push is only optimised over
concatenate for large arrays (and probably only when pushing a single element). Still,
push should never be slower than
concatenate, and is often faster, so using
push universally makes sense.