mirror of
https://github.com/lukaszraczylo/go-telegram.git
synced 2026-06-05 22:43:59 +00:00
75c7ce3119
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.
Cross-library benchmarks
Apples-to-apples micro-benchmarks comparing lukaszraczylo/go-telegram against the five most-starred Go Telegram libraries:
github.com/go-telegram-bot-api/telegram-bot-api/v5gopkg.in/telebot.v3(tucnak)github.com/go-telegram/botgithub.com/mymmrac/telegogithub.com/NicoNex/echotron/v3
Lives in its own Go module so competitor dependencies don't leak into the main repo's go.mod.
Run
go test -count=10 -bench=. -benchmem | tee results/raw.txt
go install golang.org/x/perf/cmd/benchstat@latest # one-time
benchstat results/raw.txt > results/benchstat.txt
Hot paths covered
| File | Path |
|---|---|
webhook_bench_test.go |
Decode small text-message Update from JSON |
unmarshal_bench_test.go |
Decode large Update (entities + reply markup + photo array) |
call_bench_test.go |
sendMessage round-trip against httptest.Server |
dispatch_bench_test.go |
Route an Update through 20 registered handlers (worst-case match) |
Fixtures
shared/fixtures.go defines the JSON payloads and the mock HTTP server. Every library decodes the same bytes; every round-trip hits the same canned response.
Latest results
See ../../docs/benchmarks/2026-05-10-comparison.md for the rendered comparison.