mirror of
https://github.com/lukaszraczylo/go-telegram.git
synced 2026-07-07 23:44:39 +00:00
perf(client): pool req-body buffer + manual http.Request with cached URL
Two changes that together cut allocs/call from 15 to 13 (client-internal bench) and per-call CPU from 600ns to 455ns (-24%) on the no-HTTP path: 1. Codec gets an optional BodyEncoder extension (MarshalTo io.Writer). When present, encodeJSONBody stream-encodes the request directly into a pooled *bytes.Buffer instead of allocating a [2-step] Marshal+Reader pair. DefaultCodec implements it via goccy/go-json.NewEncoder. 2. *Bot caches the parsed base URL on construction. buildRequest skips net/http.NewRequestWithContext for the common case and constructs *http.Request manually — clones the URL by value, sets the method path, and populates ContentLength + GetBody from the body's concrete type so RetryDoer's body-replay across attempts still works. Cross-library bench (sendMessage round-trip vs httptest.Server): -2 allocs/call (104 -> 102), bytes -1.2%, time within noise (real HTTP plumbing dominates). The CPU win is visible on synthetic stub-doer benches and translates to lower GC pressure on sustained-throughput workloads. Slow-path fallback preserved for codecs that don't implement BodyEncoder and for *Bot instances where url.Parse on the configured base failed — they take the original NewRequestWithContext path.
This commit is contained in:
@@ -326,10 +326,10 @@ Apples-to-apples micro-benchmarks against the five most-starred Go Telegram libr
|
||||
|
||||
| Path | Fastest | Our position |
|
||||
|------|---------|--------------|
|
||||
| Webhook decode (small Update) | **ours** — 1.74 µs / 11 allocs | 1st of 6 |
|
||||
| Large Update unmarshal (unions + reply markup) | **ours** — 6.67 µs / 34 allocs | 1st of 6 |
|
||||
| `sendMessage` round-trip (mock server) | telego — 36.3 µs / 48 allocs | 2nd of 5 |
|
||||
| Dispatcher routing (20 handlers, last matches) | **ours** — 101 ns / 3 allocs | 1st of 3 |
|
||||
| Webhook decode (small Update) | **ours** — 1.83 µs / 11 allocs | 1st of 6 |
|
||||
| Large Update unmarshal (unions + reply markup) | **ours** — 6.73 µs / 34 allocs | 1st of 6 |
|
||||
| `sendMessage` round-trip (mock server) | telego — 35.8 µs / 48 allocs | 2nd of 5 |
|
||||
| Dispatcher routing (20 handlers, last matches) | **ours** — 98 ns / 3 allocs | 1st of 3 |
|
||||
|
||||
Full tables, caveats, and reproduction steps: **[`docs/benchmarks/2026-05-10-comparison.md`](docs/benchmarks/2026-05-10-comparison.md)**.
|
||||
|
||||
|
||||
Reference in New Issue
Block a user