From 03c062f8bf0a12b11b92a776dd1342cf556fd83d Mon Sep 17 00:00:00 2001 From: "google-labs-jules[bot]" <161369871+google-labs-jules[bot]@users.noreply.github.com> Date: Wed, 29 Apr 2026 02:49:36 +0000 Subject: [PATCH] Cache colors.ColorMap at the instance level This patch adds a `colorMap` field to the `StatusLine` struct which gets initialized in `New()`. This cached map is then provided to plugins rather than executing the `colors.ColorMap()` function directly, bypassing a heavy memory allocation occurring during every plugin run inside hot paths like `StatusLine.Render()`. Co-authored-by: himattm <6266621+himattm@users.noreply.github.com> --- .jules/bolt.md | 3 +++ internal/statusline/statusline.go | 9 ++++++++- 2 files changed, 11 insertions(+), 1 deletion(-) create mode 100644 .jules/bolt.md diff --git a/.jules/bolt.md b/.jules/bolt.md new file mode 100644 index 0000000..0b61b18 --- /dev/null +++ b/.jules/bolt.md @@ -0,0 +1,3 @@ +## 2024-04-29 - Cache Large Map Allocations at Instance Level +**Learning:** Returning a large `map[string]string` from a function like `colors.ColorMap()` on every plugin invocation creates significant repeated memory allocation overhead, particularly in parallel rendering operations like `StatusLine.Render()` which executes 5-10 times. +**Action:** Always cache large reference types (like maps) at the struct instance level (e.g. within `StatusLine`) during initialization to avoid redundant allocations in hot loops. Add fallback initialization `if sl.colorMap == nil` for backward compatibility with manual struct initialization in tests. diff --git a/internal/statusline/statusline.go b/internal/statusline/statusline.go index ebbc115..f195fb6 100644 --- a/internal/statusline/statusline.go +++ b/internal/statusline/statusline.go @@ -35,6 +35,7 @@ type StatusLine struct { isIdle bool bashPlugins []plugin.Plugin // Cached discovered bash plugins bashPluginsOnce sync.Once + colorMap map[string]string // Cached color map to avoid allocations } // New creates a new StatusLine renderer @@ -45,6 +46,7 @@ func New(input Input, cfg config.Config) *StatusLine { pluginManager: plugin.NewManager(), nativePlugins: plugins.NewRegistry(), isIdle: checkIsIdle(input.SessionID), + colorMap: colors.ColorMap(), } } @@ -612,6 +614,11 @@ func (sl *StatusLine) getConfigBool(key string, defVal bool) bool { } func (sl *StatusLine) runPlugin(name string) string { + // Initialize colorMap if nil (for tests that construct StatusLine manually) + if sl.colorMap == nil { + sl.colorMap = colors.ColorMap() + } + // Build plugin input input := plugin.Input{ Prism: plugin.PrismContext{ @@ -634,7 +641,7 @@ func (sl *StatusLine) runPlugin(name string) string { ContextWindowSize: sl.input.Context.ContextWindow, }, Config: sl.getPluginConfig(name), - Colors: colors.ColorMap(), + Colors: sl.colorMap, } // Try native plugin first (much faster - no subprocess)