mirror of
https://github.com/lukaszraczylo/go-telegram.git
synced 2026-06-05 22:43:59 +00:00
perf(dispatch): typed Context.Command/CommandArgs/RegexMatch fields
Move the three conventional Values keys ("command", "command_args", "regex_match") to typed fields on Context. Router and group routing write the fields directly; the Values map is allocated lazily via the new Set method and reserved for user-defined custom keys.
Allocation impact (M4 Max, b.Loop()):
DispatchCommand: 5 allocs/op -> 1, 153ns -> 69ns (-55%)
DispatchTextRegex: 5 allocs/op -> 2, 181ns -> 107ns (-41%)
DispatchFilter: 2 allocs/op -> 1, 32ns -> 19ns (-41%)
NewContext: 5.79ns -> 1.60ns
Trade-off: Context struct grew from ~48B to ~96B (three new fields), so filter-only paths pay ~50B more per dispatch. Command/regex paths save ~320B + 4 allocs each, which dominates for typical bot workloads.
Handlers reading c.Values["command"], c.Values["command_args"], or c.Values["regex_match"] now get nil; the typed fields c.Command, c.CommandArgs, c.RegexMatch are the new accessors. Custom keys still work via c.Set(k, v) and c.Values[k].
This commit is contained in:
@@ -21,7 +21,7 @@ func handleStart(c *dispatch.Context, m *api.Message) error {
|
||||
}
|
||||
|
||||
func handleCallback(c *dispatch.Context, q *api.CallbackQuery) error {
|
||||
groups := c.Values["regex_match"].([]string)
|
||||
groups := c.RegexMatch
|
||||
current, _ := strconv.Atoi(groups[1])
|
||||
if groups[2] == "inc" {
|
||||
current++
|
||||
|
||||
@@ -42,7 +42,7 @@ const (
|
||||
func makeCtx(bot *client.Bot, upd *api.Update, extra map[string]any) *dispatch.Context {
|
||||
c := dispatch.NewContext(context.Background(), bot, upd)
|
||||
for k, v := range extra {
|
||||
c.Values[k] = v
|
||||
c.Set(k, v)
|
||||
}
|
||||
return c
|
||||
}
|
||||
@@ -82,7 +82,9 @@ func TestHandleStart_SendsInitialKeyboard(t *testing.T) {
|
||||
|
||||
func callbackCtx(bot *client.Bot, q *api.CallbackQuery, groups []string) *dispatch.Context {
|
||||
upd := &api.Update{UpdateID: 1, CallbackQuery: q}
|
||||
return makeCtx(bot, upd, map[string]any{"regex_match": groups})
|
||||
c := makeCtx(bot, upd, nil)
|
||||
c.RegexMatch = groups
|
||||
return c
|
||||
}
|
||||
|
||||
func callbackQuery(data string, msgID int64, chatID int64) *api.CallbackQuery {
|
||||
|
||||
@@ -111,8 +111,7 @@ func main() {
|
||||
|
||||
// page:<n> callbacks — edit message in-place.
|
||||
router.OnCallback(`^page:(\d+)$`, func(c *dispatch.Context, q *api.CallbackQuery) error {
|
||||
groups := c.Values["regex_match"].([]string)
|
||||
page, _ := strconv.Atoi(groups[1])
|
||||
page, _ := strconv.Atoi(c.RegexMatch[1])
|
||||
|
||||
// Acknowledge the tap first.
|
||||
_, _ = api.AnswerCallbackQuery(c.Ctx, c.Bot, &api.AnswerCallbackQueryParams{
|
||||
|
||||
Reference in New Issue
Block a user