Page MenuHomeFeedback Tracker

Add "parseArray" command
Closed, ResolvedPublic

Description

We have parseNumber command that would convert a string to number

parseNumber "25" => 25

Now we need a command that would do the same to an array

so instead of

call compile "[1,2,3]"

it would just

parseArray "[1,2,3]" => [1,2,3]

Invalid string should return [] in the same way parseNumber returns 0

Why different command? Call compile on a long string is very slow. It can freeze the game for a second. parseArray is expected to be a much faster dedicated command.

arrayToString would be great as well, one condition though, it will have to preserve the number precision when converting to string.

both needed for fast database operations

Details

Legacy ID
4177319415
Severity
None
Resolution
Fixed
Reproducibility
Always
Category
Feature Request

Event Timeline

Killzone_Kid edited Additional Information. (Show Details)
Killzone_Kid set Category to Feature Request.
Killzone_Kid set Reproducibility to Always.
Killzone_Kid set Severity to None.
Killzone_Kid set Resolution to Fixed.
Killzone_Kid set Legacy ID to 4177319415.May 7 2016, 5:37 PM

<i>parseArray is expected to be a much faster dedicated command.</i>

I don't see how that could be possible. parseNumber probably just calls atof, this proposed command will have to understand SQF grammar to correctly interpret the contained data types.

All it needs to understand is

anything in "" or '' is a string
true or false is boolean
anything in [] is another array like this one
and 0-9 is a number

I think we can safely exclude objects and variables.

Of course if we could just pass and receive array from extension...

If you compare the speed of for example

a = [1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1];

and

a = call compile "[1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1]";

the latter is almost 5 times slower.

Why can't parseArray just remove "" and treat the content as if I typed array? I am not 100% on how SQF gets converted into C++, but would this "[]" to [] conversion be possible before SQF becomes C++ code?

Or maybe modify getArray so that instead of config entry we can pass value formatted like config entry?

getArray {1,1,1,1,1,1,1}?

I've compared

a = 123456;
vs
a = parseNumber "123456";
vs
a = call compile "123456";

although parseNumber is slightly slower than 1st example it is much faster than call compile workaround.

<i>Why can't parseArray just remove "" and treat the content as if I typed array? I am not 100% on how SQF gets converted into C++, but would this "[]" to [] conversion be possible before SQF becomes C++ code?</i>

Well it essentially does that. The reason the former is much faster is because it was <i>already</i> compiled alongside the rest of the script. If you were to measure the time it takes for the <b>whole</b> script to call compile preprocessFile you'd notice little difference.

SQF never becomes C++ code, it just gets broken down to instructions that are interpreted by the engine (which just happens to be written in C++).

<i>although parseNumber is slightly slower than 1st example it is much faster than call compile workaround.</i>

When you use <b>parseNumber</b> it already knows the input string (should) contain a number so it just (presumably) calls atof to get the numeric value.

With <b>compile</b> the script interpreter has no idea what it could find in the string so it has to interpret it.

@Deadfast what about getArray? It reads config entry expecting array, can it be tricked to read a string from sqf?

<b>getArray</b> doesn't do any parsing, it just returns the array value that is held in memory since the game start, which is when the entire config will have been parsed.

So there is a parser that parses config arrays, why can't it be used again? The difference between config arrays and sqf arrays is {} instead of []. I would be happy if this parser was limited to strings booleans and numbers.

Setting performance aside for a moment, the other problem with the call compile is that it allows the parameter to have code in it, which will immediately be executed. Especially while there is no signing for extensions, this is a bad thing.

Back to performance:
I've gotten the compile function to lock the game up for >20 minutes. (It wasn't completely accidental but the magnitude was surprising.)
Basically I don't think the performance of a parseArray would get anywhere near as bad because there's a lot it doesn't need to handle, like the creation of a value of type CODE.

@MaHuJa new substring functionality can be used to cherry pick results from extension return. You can basically get numbers and strings avoiding call compile

res = "[123,'hello']";
parseNumber (res select [1,3]) 123 number
res select [6,5]
hello string

better than nothing I guess

This was the first place I learned of the substrings method.

Combined with find, this makes it easier to make a parseArray ourselves.
Especially if you don't require the regular syntax for it.

But if you apply the magic words "fixed size records" then things can really take off.
_res1 = _res select [0,10];
_res2 = _res select [10,10];
_res3 = parsenumber (_res select [20,10]);