Use bytearray for request body accumulation (#2845)

* Use bytearray for request body accumulation

Accumulating request body with bytes += creates a new bytes object on
every chunk, leading to O(n^2) allocation for fragmented bodies.
bytearray extends in-place (amortized O(1)), avoiding the quadratic cost.

* Add fragmented body benchmark for chunked body accumulation

Sends 100KB in 390 x 256-byte chunks to exercise the body += path
that triggers O(n^2) allocation with bytes concatenation.

* Revert "Add fragmented body benchmark for chunked body accumulation"

This reverts commit 47662509c1.
This commit is contained in:
Marcelo Trylesinski 2026-03-15 17:16:56 +01:00 committed by GitHub
parent 3f3ebee20f
commit b3c69da8c1
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 6 additions and 6 deletions

View File

@ -397,7 +397,7 @@ class RequestResponseCycle:
self.waiting_for_100_continue = conn.they_are_waiting_for_100_continue
# Request state
self.body = b""
self.body = bytearray()
self.more_body = True
# Response state
@ -543,8 +543,8 @@ class RequestResponseCycle:
message: HTTPRequestEvent = {
"type": "http.request",
"body": self.body,
"body": bytes(self.body),
"more_body": self.more_body,
}
self.body = b""
self.body = bytearray()
return message

View File

@ -401,7 +401,7 @@ class RequestResponseCycle:
self.waiting_for_100_continue = expect_100_continue
# Request state
self.body = b""
self.body = bytearray()
self.more_body = True
# Response state
@ -572,6 +572,6 @@ class RequestResponseCycle:
if self.disconnected or self.response_complete:
return {"type": "http.disconnect"}
message: HTTPRequestEvent = {"type": "http.request", "body": self.body, "more_body": self.more_body}
self.body = b""
message: HTTPRequestEvent = {"type": "http.request", "body": bytes(self.body), "more_body": self.more_body}
self.body = bytearray()
return message