Skip to content

Commit 88eabe7

Browse files
authored
perf: recording performance optimizations (#83)
* feat: cache vehicle exclusion lists at init instead of parsing per vehicle * feat: cache marker exclusion list instead of parsing per event * perf: use findIf instead of count for APC classification * perf: cache player scores string, skip joinString when unchanged * perf: only recalculate unit type on weapon change instead of every 10 frames * fix: repair unitData deduplication — fix variable name and exclude frame from comparison The state comparison at captureLoop:170 never worked due to two bugs: 1. Read from "unitData" but wrote to "OCAP_unitData" (QGVARMAIN mismatch) 2. Frame number at index 8 changed every frame, making comparison always unequal Fix uses a 0 placeholder for frame during comparison and stores a deep copy. This eliminates redundant extension calls for unchanged units (dead, stationary). * perf: replace chained select with counting in telemetry loop
1 parent 6e31c86 commit 88eabe7

5 files changed

Lines changed: 112 additions & 59 deletions

File tree

addons/recorder/fnc_captureLoop.sqf

Lines changed: 18 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -130,9 +130,11 @@ GVAR(PFHObject) = [
130130
};
131131
if (!_justInitialized && {!_isExcluded}) then {
132132
private _unitRole = _x getVariable [QGVARMAIN(unitType), ""];
133-
if (GVAR(captureFrameNo) % 10 == 0 || _unitRole == "") then {
133+
private _weapons = [primaryWeapon _x, secondaryWeapon _x];
134+
if (_weapons isNotEqualTo (_x getVariable [QGVAR(lastWeapons), []]) || _unitRole == "") then {
134135
_unitRole = [_x] call FUNC(getUnitType);
135136
_x setVariable [QGVARMAIN(unitType), _unitRole];
137+
_x setVariable [QGVAR(lastWeapons), _weapons];
136138
};
137139

138140
private _lifeState = 0;
@@ -147,6 +149,14 @@ GVAR(PFHObject) = [
147149
_pos = getPosASL _x;
148150
private _unitGroup = group _x;
149151

152+
private _scores = getPlayerScores _x;
153+
private _scoresStr = _x getVariable [QGVAR(lastScoresStr), ""];
154+
if (_scores isNotEqualTo (_x getVariable [QGVAR(lastScores), []])) then {
155+
_scoresStr = _scores joinString ",";
156+
_x setVariable [QGVAR(lastScores), _scores];
157+
_x setVariable [QGVAR(lastScoresStr), _scoresStr];
158+
};
159+
150160
private _unitData = [
151161
(_x getVariable QGVARMAIN(id)), //1
152162
_pos, //2
@@ -156,20 +166,21 @@ GVAR(PFHObject) = [
156166
if (alive _x) then {name _x} else {""}, //6
157167
BOOL(isPlayer _x), //7
158168
_unitRole, //8
159-
GVAR(captureFrameNo), // frame 9
169+
0, // frame placeholder for comparison (set before sending) 9
160170
if (!isNil "ace_medical_status_fnc_hasStableVitals") then {BOOL([_x] call ace_medical_status_fnc_hasStableVitals)} else {true}, // 10
161171
if (!isNil "ace_medical_status_fnc_isBeingDragged") then {BOOL([_x] call ace_medical_status_fnc_isBeingDragged)} else {false}, // 11
162-
(getPlayerScores _x) joinString ",", // scores 12
172+
_scoresStr, // scores 12
163173
_x call CBA_fnc_vehicleRole, // vehicle role 13
164174
if (!isNull objectParent _x) then {(objectParent _x) getVariable [QGVARMAIN(id), -1]} else {-1}, // 14
165175
stance _x, // 15
166176
groupID _unitGroup, // 16 group name (dynamic)
167177
str side _unitGroup // 17 side (dynamic)
168178
];
169179

170-
if (_x getVariable ["unitData", []] isNotEqualTo _unitData) then {
180+
if (_x getVariable [QGVARMAIN(unitData), []] isNotEqualTo _unitData) then {
181+
_x setVariable [QGVARMAIN(unitData), +_unitData];
182+
_unitData set [8, GVAR(captureFrameNo)];
171183
[":SOLDIER:STATE:", _unitData] call EFUNC(extension,sendData);
172-
_x setVariable [QGVARMAIN(unitData), _unitData];
173184
};
174185
};
175186
false
@@ -182,7 +193,7 @@ GVAR(PFHObject) = [
182193
_class = _vehType call FUNC(getClass);
183194
private _vic = _x;
184195
private _toExcludeKind = false;
185-
private _kindList = parseSimpleArray EGVAR(settings,excludeKindFromRecord);
196+
private _kindList = GVAR(excludeKindList);
186197
if (_kindList isNotEqualTo []) then {
187198
{
188199
if (_vic isKindOf _x) exitWith {
@@ -191,7 +202,7 @@ GVAR(PFHObject) = [
191202
} forEach _kindList;
192203
};
193204
private _toExcludeClass = false;
194-
private _classList = parseSimpleArray EGVAR(settings,excludeClassFromRecord);
205+
private _classList = GVAR(excludeClassList);
195206
if (_classList isNotEqualTo []) then {
196207
{
197208
if (typeOf _vic == _x) exitWith {

addons/recorder/fnc_handleMarkers.sqf

Lines changed: 26 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -161,6 +161,12 @@ EGVAR(listener,markers) = [QGVARMAIN(handleMarker), {
161161

162162
// handle created markers
163163
{
164+
GVAR(excludeMarkerList) = if (!isNil QEGVAR(settings,excludeMarkerFromRecord)) then {
165+
parseSimpleArray EGVAR(settings,excludeMarkerFromRecord)
166+
} else {
167+
[]
168+
};
169+
164170
/*
165171
Event Handler: MarkerCreated
166172
Description:
@@ -181,13 +187,11 @@ EGVAR(listener,markers) = [QGVARMAIN(handleMarker), {
181187
// check for excluded values in marker name. if name contains at least one value, skip sending traffic to server
182188
// if value is undefined, then skip
183189
private _isExcluded = false;
184-
if (!isNil QEGVAR(settings,excludeMarkerFromRecord)) then {
185-
{
186-
if ((str _marker) find _x >= 0) exitWith {
187-
_isExcluded = true;
188-
};
189-
} forEach (parseSimpleArray EGVAR(settings,excludeMarkerFromRecord));
190-
};
190+
{
191+
if ((str _marker) find _x >= 0) exitWith {
192+
_isExcluded = true;
193+
};
194+
} forEach GVAR(excludeMarkerList);
191195
if (_isExcluded) exitWith {};
192196

193197
private _event = _this;
@@ -234,13 +238,11 @@ EGVAR(listener,markers) = [QGVARMAIN(handleMarker), {
234238
// check for excluded values in marker name. if name contains at least one value, skip sending traffic to server
235239
// if value is undefined, then skip
236240
private _isExcluded = false;
237-
if (!isNil QEGVAR(settings,excludeMarkerFromRecord)) then {
238-
{
239-
if ((str _marker) find _x >= 0) exitWith {
240-
_isExcluded = true;
241-
};
242-
} forEach (parseSimpleArray EGVAR(settings,excludeMarkerFromRecord));
243-
};
241+
{
242+
if ((str _marker) find _x >= 0) exitWith {
243+
_isExcluded = true;
244+
};
245+
} forEach GVAR(excludeMarkerList);
244246
if (_isExcluded) exitWith {};
245247

246248
private _pos = ATLToASL (markerPos [_marker, true]);
@@ -269,13 +271,11 @@ EGVAR(listener,markers) = [QGVARMAIN(handleMarker), {
269271
// check for excluded values in marker name. if name contains at least one value, skip sending traffic to server
270272
// if value is undefined, then skip
271273
private _isExcluded = false;
272-
if (!isNil QEGVAR(settings,excludeMarkerFromRecord)) then {
273-
{
274-
if ((str _marker) find _x > -1) exitWith {
275-
_isExcluded = true;
276-
};
277-
} forEach (parseSimpleArray EGVAR(settings,excludeMarkerFromRecord));
278-
};
274+
{
275+
if ((str _marker) find _x > -1) exitWith {
276+
_isExcluded = true;
277+
};
278+
} forEach GVAR(excludeMarkerList);
279279
if (_isExcluded) exitWith {};
280280

281281
[QGVARMAIN(handleMarker), ["DELETED", _marker, player]] call CBA_fnc_serverEvent;
@@ -294,13 +294,11 @@ EGVAR(listener,markers) = [QGVARMAIN(handleMarker), {
294294
// check for excluded values in marker name. if name contains at least one value, skip sending traffic to server
295295
// if value is undefined, then skip
296296
private _isExcluded = false;
297-
if (!isNil QEGVAR(settings,excludeMarkerFromRecord)) then {
298-
{
299-
if ((_marker) find _x >= 0) exitWith {
300-
_isExcluded = true;
301-
};
302-
} forEach (parseSimpleArray EGVAR(settings,excludeMarkerFromRecord));
303-
};
297+
{
298+
if ((_marker) find _x >= 0) exitWith {
299+
_isExcluded = true;
300+
};
301+
} forEach GVAR(excludeMarkerList);
304302
if (_isExcluded) then {continue};
305303

306304

addons/recorder/fnc_init.sqf

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,15 @@ GVAR(autoStart) = EGVAR(settings,autoStart);
7979
*/
8080
GVAR(minMissionTime) = EGVAR(settings,minMissionTime);
8181

82+
GVAR(excludeKindList) = parseSimpleArray EGVAR(settings,excludeKindFromRecord);
83+
GVAR(excludeClassList) = parseSimpleArray EGVAR(settings,excludeClassFromRecord);
84+
85+
GVAR(excludeMarkerList) = if (!isNil QEGVAR(settings,excludeMarkerFromRecord)) then {
86+
parseSimpleArray EGVAR(settings,excludeMarkerFromRecord)
87+
} else {
88+
[]
89+
};
90+
8291
/*
8392
VARIABLE: OCAP_version
8493
Global variable that represents the version of OCAP addon being used [String]

addons/recorder/fnc_isKindOfApc.sqf

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -23,10 +23,6 @@ Author:
2323
---------------------------------------------------------------------------- */
2424
#include "script_component.hpp"
2525

26-
_bool = false;
27-
{
28-
if (_this isKindOf _x) exitWith {_bool = true;};
29-
false;
30-
} count ["Wheeled_APC_F","Tracked_APC","APC_Wheeled_01_base_F","APC_Wheeled_02_base_F",
31-
"APC_Wheeled_03_base_F","APC_Tracked_01_base_F","APC_Tracked_02_base_F","APC_Tracked_03_base_F"];
32-
_bool
26+
["Wheeled_APC_F","Tracked_APC","APC_Wheeled_01_base_F","APC_Wheeled_02_base_F",
27+
"APC_Wheeled_03_base_F","APC_Tracked_01_base_F","APC_Tracked_02_base_F","APC_Tracked_03_base_F"]
28+
findIf {_this isKindOf _x} != -1

addons/recorder/fnc_telemetryLoop.sqf

Lines changed: 56 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -41,25 +41,64 @@ Author:
4141
private _sideData = [];
4242
{
4343
private _s = _x;
44-
private _sUnits = _allUnits select {side _x isEqualTo _s};
45-
private _sDead = _allDeadMen select {side _x isEqualTo _s};
46-
private _sGroups = _allGroups select {side _x isEqualTo _s};
47-
private _sVeh = _vehicles select {side _x isEqualTo _s};
48-
49-
private _localUnits = _sUnits select {local _x};
50-
private _remoteUnits = _sUnits select {!local _x};
51-
private _localDead = _sDead select {local _x};
52-
private _remoteDead = _sDead select {!local _x};
53-
private _localGroups = _sGroups select {local _x};
54-
private _remoteGroups = _sGroups select {!local _x};
55-
private _localVeh = _sVeh select {local _x && !(_x isKindOf "WeaponHolderSimulated")};
56-
private _remoteVeh = _sVeh select {!local _x && !(_x isKindOf "WeaponHolderSimulated")};
57-
private _localWH = _sVeh select {local _x && _x isKindOf "WeaponHolderSimulated"};
58-
private _remoteWH = _sVeh select {!local _x && _x isKindOf "WeaponHolderSimulated"};
44+
private _localUnits = 0;
45+
private _localAlive = 0;
46+
private _remoteUnits = 0;
47+
private _remoteAlive = 0;
48+
{
49+
if (side _x isEqualTo _s) then {
50+
if (local _x) then {
51+
_localUnits = _localUnits + 1;
52+
if (alive _x) then { _localAlive = _localAlive + 1 };
53+
} else {
54+
_remoteUnits = _remoteUnits + 1;
55+
if (alive _x) then { _remoteAlive = _remoteAlive + 1 };
56+
};
57+
};
58+
} forEach _allUnits;
59+
60+
private _localDead = 0;
61+
private _remoteDead = 0;
62+
{
63+
if (side _x isEqualTo _s) then {
64+
if (local _x) then {
65+
_localDead = _localDead + 1;
66+
} else {
67+
_remoteDead = _remoteDead + 1;
68+
};
69+
};
70+
} forEach _allDeadMen;
71+
72+
private _localGroups = 0;
73+
private _remoteGroups = 0;
74+
{
75+
if (side _x isEqualTo _s) then {
76+
if (local _x) then {
77+
_localGroups = _localGroups + 1;
78+
} else {
79+
_remoteGroups = _remoteGroups + 1;
80+
};
81+
};
82+
} forEach _allGroups;
83+
84+
private _localVeh = 0;
85+
private _remoteVeh = 0;
86+
private _localWH = 0;
87+
private _remoteWH = 0;
88+
{
89+
if (side _x isEqualTo _s) then {
90+
private _isWH = _x isKindOf "WeaponHolderSimulated";
91+
if (local _x) then {
92+
if (_isWH) then { _localWH = _localWH + 1 } else { _localVeh = _localVeh + 1 };
93+
} else {
94+
if (_isWH) then { _remoteWH = _remoteWH + 1 } else { _remoteVeh = _remoteVeh + 1 };
95+
};
96+
};
97+
} forEach _vehicles;
5998

6099
_sideData pushBack [
61-
[count _localUnits, {alive _x} count _localUnits, count _localDead, count _localGroups, count _localVeh, count _localWH],
62-
[count _remoteUnits, {alive _x} count _remoteUnits, count _remoteDead, count _remoteGroups, count _remoteVeh, count _remoteWH]
100+
[_localUnits, _localAlive, _localDead, _localGroups, _localVeh, _localWH],
101+
[_remoteUnits, _remoteAlive, _remoteDead, _remoteGroups, _remoteVeh, _remoteWH]
63102
];
64103
} forEach [east, west, independent, civilian];
65104

0 commit comments

Comments
 (0)