fix: track the JSON length instead of recounting it

Every append found the end of the buffer with strlen(), up to four
times per append and four appends per field, so building a response
cost the square of its size. /discovery fills a 4 KB buffer and spent
about 195 ms of its ~210 ms there (shades 126 ms, groups 69 ms), all on
the async_tcp task that serves every socket and web request.

Keep the length in the formatter and write every append at the end
through one helper. The web response and socket event subclasses and
ControllerChunker use the tracked length too. Output is unchanged.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
cjkas 2026-10-12 16:04:13 +02:00
parent 55b1db4508
commit a8bb377957
5 changed files with 86 additions and 33 deletions

View file

@ -555,7 +555,7 @@ private:
serializeGitVersion(fmt);
fmt.endObject();
fmt.beginArray("rooms");
unitLen = strlen(unit);
unitLen = fmt.length();
section = S_ROOMS;
idx = 0;
firstInArray = true;
@ -577,7 +577,7 @@ private:
fmt.beginObject();
serializeRoom(&somfy.rooms[idx], fmt);
fmt.endObject();
unitLen = pos + strlen(unit + pos);
unitLen = pos + fmt.length();
idx++;
firstInArray = false;
return;
@ -599,7 +599,7 @@ private:
fmt.beginObject();
serializeShade(&somfy.shades[idx], fmt);
fmt.endObject();
unitLen = pos + strlen(unit + pos);
unitLen = pos + fmt.length();
idx++;
firstInArray = false;
return;
@ -622,7 +622,7 @@ private:
fmt.beginObject();
serializeGroupRef(g, fmt);
fmt.beginArray("linkedShades");
unitLen = pos + strlen(unit + pos);
unitLen = pos + fmt.length();
lsIdx = 0;
firstInArray = false;
firstInLSArray = true;
@ -650,7 +650,7 @@ private:
fmt.beginObject();
serializeShadeRef(lshade, fmt);
fmt.endObject();
unitLen = pos + strlen(unit + pos);
unitLen = pos + fmt.length();
lsIdx++;
firstInLSArray = false;
return;