Files
lukaszraczylo 75c7ce3119 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.
2026-05-10 22:36:57 +01:00

76 lines
7.7 KiB
Plaintext

goos: darwin
goarch: arm64
pkg: github.com/lukaszraczylo/go-telegram/test/benchmarks
cpu: Apple M4 Max
│ /Users/nvm/Documents/projects/private/go-telegram/test/benchmarks/results/raw.txt │
│ sec/op │
Call_ours-16 39.83µ ± 4%
Call_gotba-16 42.03µ ± 4%
Call_telebot-16 43.41µ ± 1%
Call_gobot-16 61.19µ ± 1%
Call_telego-16 35.84µ ± 1%
Dispatch_ours-16 98.46n ± 2%
Dispatch_telebot-16 270.9n ± 2%
Dispatch_gobot-16 246.1n ± 1%
LargeUnmarshal_ours-16 6.726µ ± 1%
LargeUnmarshal_gotba-16 8.066µ ± 1%
LargeUnmarshal_telebot-16 10.19µ ± 1%
LargeUnmarshal_gobot-16 8.231µ ± 1%
LargeUnmarshal_telego-16 7.849µ ± 2%
LargeUnmarshal_echotron-16 8.123µ ± 1%
Webhook_ours-16 1.832µ ± 4%
Webhook_gotba-16 2.082µ ± 0%
Webhook_telebot-16 2.194µ ± 1%
Webhook_gobot-16 2.082µ ± 1%
Webhook_telego-16 2.143µ ± 2%
Webhook_echotron-16 2.039µ ± 1%
geomean 4.658µ
│ /Users/nvm/Documents/projects/private/go-telegram/test/benchmarks/results/raw.txt │
│ B/op │
Call_ours-16 11.09Ki ± 1%
Call_gotba-16 10.97Ki ± 0%
Call_telebot-16 13.15Ki ± 0%
Call_gobot-16 13.50Ki ± 0%
Call_telego-16 6.547Ki ± 0%
Dispatch_ours-16 128.0 ± 0%
Dispatch_telebot-16 678.5 ± 0%
Dispatch_gobot-16 48.00 ± 0%
LargeUnmarshal_ours-16 5.875Ki ± 0%
LargeUnmarshal_gotba-16 3.438Ki ± 0%
LargeUnmarshal_telebot-16 5.594Ki ± 0%
LargeUnmarshal_gobot-16 4.703Ki ± 0%
LargeUnmarshal_telego-16 6.600Ki ± 0%
LargeUnmarshal_echotron-16 4.219Ki ± 0%
Webhook_ours-16 2.180Ki ± 0%
Webhook_gotba-16 1.461Ki ± 0%
Webhook_telebot-16 1.773Ki ± 0%
Webhook_gobot-16 1.789Ki ± 0%
Webhook_telego-16 3.058Ki ± 0%
Webhook_echotron-16 1.680Ki ± 0%
geomean 2.699Ki
│ /Users/nvm/Documents/projects/private/go-telegram/test/benchmarks/results/raw.txt │
│ allocs/op │
Call_ours-16 102.0 ± 0%
Call_gotba-16 125.0 ± 0%
Call_telebot-16 139.0 ± 0%
Call_gobot-16 176.0 ± 0%
Call_telego-16 48.00 ± 0%
Dispatch_ours-16 3.000 ± 0%
Dispatch_telebot-16 5.000 ± 0%
Dispatch_gobot-16 1.000 ± 0%
LargeUnmarshal_ours-16 34.00 ± 0%
LargeUnmarshal_gotba-16 56.00 ± 0%
LargeUnmarshal_telebot-16 60.00 ± 0%
LargeUnmarshal_gobot-16 50.00 ± 0%
LargeUnmarshal_telego-16 31.00 ± 0%
LargeUnmarshal_echotron-16 56.00 ± 0%
Webhook_ours-16 11.00 ± 0%
Webhook_gotba-16 17.00 ± 0%
Webhook_telebot-16 17.00 ± 0%
Webhook_gobot-16 16.00 ± 0%
Webhook_telego-16 11.00 ± 0%
Webhook_echotron-16 16.00 ± 0%
geomean 26.00