mirror of
https://github.com/lukaszraczylo/go-telegram.git
synced 2026-06-10 23:09:04 +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:
+4
-4
@@ -467,8 +467,8 @@ func (r *Router) handleMessage(c *Context, m *api.Message) error {
|
||||
if cmd, args, ok := extractCommand(m); ok {
|
||||
for _, route := range r.commands {
|
||||
if route.cmd == cmd {
|
||||
c.Values["command"] = cmd
|
||||
c.Values["command_args"] = args
|
||||
c.Command = cmd
|
||||
c.CommandArgs = args
|
||||
return route.handler(c, m)
|
||||
}
|
||||
}
|
||||
@@ -477,7 +477,7 @@ func (r *Router) handleMessage(c *Context, m *api.Message) error {
|
||||
if m.Text != "" {
|
||||
for _, route := range r.texts {
|
||||
if subs := route.re.FindStringSubmatch(m.Text); subs != nil {
|
||||
c.Values["regex_match"] = subs
|
||||
c.RegexMatch = subs
|
||||
return route.handler(c, m)
|
||||
}
|
||||
}
|
||||
@@ -495,7 +495,7 @@ func (r *Router) handleMessage(c *Context, m *api.Message) error {
|
||||
func (r *Router) handleCallback(c *Context, q *api.CallbackQuery) error {
|
||||
for _, route := range r.callbacks {
|
||||
if subs := route.re.FindStringSubmatch(q.Data); subs != nil {
|
||||
c.Values["regex_match"] = subs
|
||||
c.RegexMatch = subs
|
||||
return route.handler(c, q)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user