From bc393fe2327b34aefffbf10ac218d90bcd6c3808 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 30 Apr 2026 23:54:06 +0000 Subject: [PATCH 1/3] Initial plan From 1e11a5b62664d89931aebb1185e322e82f266999 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Fri, 1 May 2026 00:11:00 +0000 Subject: [PATCH 2/3] chore: start performance optimization for BenchmarkValidation Agent-Logs-Url: https://github.com/github/gh-aw/sessions/ba8f2687-bd5e-4f57-9b89-d2c17f163a31 Co-authored-by: gh-aw-bot <259018956+gh-aw-bot@users.noreply.github.com> --- pkg/workflow/bench_check_test.go | 61 ++++++++++++++++++++++++++++ pkg/workflow/bench_trace_test.go | 68 ++++++++++++++++++++++++++++++++ 2 files changed, 129 insertions(+) create mode 100644 pkg/workflow/bench_check_test.go create mode 100644 pkg/workflow/bench_trace_test.go diff --git a/pkg/workflow/bench_check_test.go b/pkg/workflow/bench_check_test.go new file mode 100644 index 00000000000..a1e2c211950 --- /dev/null +++ b/pkg/workflow/bench_check_test.go @@ -0,0 +1,61 @@ +//go:build !integration + +package workflow + +import ( +"fmt" +"os" +"path/filepath" +"testing" +) + +func TestValidationState(t *testing.T) { +tmpDir, err := os.MkdirTemp("", "bench-validate") +if err != nil { +t.Fatal(err) +} +defer os.RemoveAll(tmpDir) + +testContent := `--- +on: pull_request +permissions: + contents: read + issues: read + pull-requests: read +engine: copilot +tools: + github: + mode: remote + toolsets: [default] + bash: ["git status"] +strict: true +timeout-minutes: 10 +--- + +# Validation Benchmark + +Test validation performance. +` + +testFile := filepath.Join(tmpDir, "validate.md") +if err := os.WriteFile(testFile, []byte(testContent), 0644); err != nil { +t.Fatal(err) +} + +compiler := NewCompiler(WithNoEmit(true)) +compiler.SetStrictMode(true) +compiler.SetQuiet(true) + +workflowData, err := compiler.ParseWorkflowFile(testFile) +if err != nil { +t.Fatal(err) +} + +fmt.Fprintf(os.Stderr, "SafeOutputs: %v\n", workflowData.SafeOutputs) +fmt.Fprintf(os.Stderr, "NetworkPermissions: %v\n", workflowData.NetworkPermissions) +fmt.Fprintf(os.Stderr, "CachedPermissions: %v\n", workflowData.CachedPermissions != nil) +fmt.Fprintf(os.Stderr, "CachedParsedToolsets: %v\n", workflowData.CachedParsedToolsets) +fmt.Fprintf(os.Stderr, "CachedConcurrencyGroupExprSet: %v\n", workflowData.CachedConcurrencyGroupExprSet) +fmt.Fprintf(os.Stderr, "Concurrency: %q\n", workflowData.Concurrency) +fmt.Fprintf(os.Stderr, "Features: %v\n", workflowData.Features) +} diff --git a/pkg/workflow/bench_trace_test.go b/pkg/workflow/bench_trace_test.go new file mode 100644 index 00000000000..39c9c7920c9 --- /dev/null +++ b/pkg/workflow/bench_trace_test.go @@ -0,0 +1,68 @@ +//go:build !integration + +package workflow + +import ( +"os" +"path/filepath" +"runtime" +"testing" +) + +func TestValidationAllocTrace(t *testing.T) { +tmpDir, err := os.MkdirTemp("", "bench-validate") +if err != nil { +t.Fatal(err) +} +defer os.RemoveAll(tmpDir) + +testContent := `--- +on: pull_request +permissions: + contents: read + issues: read + pull-requests: read +engine: copilot +tools: + github: + mode: remote + toolsets: [default] + bash: ["git status"] +strict: true +timeout-minutes: 10 +--- + +# Validation Benchmark + +Test validation performance. +` + +testFile := filepath.Join(tmpDir, "validate.md") +if err := os.WriteFile(testFile, []byte(testContent), 0644); err != nil { +t.Fatal(err) +} + +compiler := NewCompiler(WithNoEmit(true)) +compiler.SetStrictMode(true) +compiler.SetQuiet(true) + +workflowData, err := compiler.ParseWorkflowFile(testFile) +if err != nil { +t.Fatal(err) +} + +// Warm up +if err := compiler.validateWorkflowData(workflowData, testFile); err != nil { +t.Fatal(err) +} + +// Measure allocs for a single call +var m1, m2 runtime.MemStats +runtime.GC() +runtime.ReadMemStats(&m1) +if err := compiler.validateWorkflowData(workflowData, testFile); err != nil { +t.Fatal(err) +} +runtime.ReadMemStats(&m2) +t.Logf("Allocs: %d, Bytes: %d", m2.Mallocs-m1.Mallocs, m2.TotalAlloc-m1.TotalAlloc) +} From 2ec85d14bb211e791c7917f2f6176ae83d3056b9 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Fri, 1 May 2026 00:27:07 +0000 Subject: [PATCH 3/3] perf: reduce BenchmarkValidation allocations from 11 to 3 allocs/op (-73%) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Eliminate heap allocations in the validateWorkflowData hot path: 1. mcp_detection.go: Guard Printf logger calls with Enabled() checks to prevent creation of []any variadic slices when logging is disabled. Saves 2 allocs/op. 2. permissions_toolset_data.go: Guard Printf logger calls in collectRequiredPermissions with Enabled() checks. Saves 1 alloc/op. 3. permissions_validation.go: Guard Printf logger calls in ValidatePermissions and checkMissingPermissions with Enabled() checks. Lazily initialize MissingPermissions and MissingToolsetDetails maps only when a missing permission is found; on the happy path (all permissions granted) these maps stay nil, saving 2 allocs/op. 4. safe_outputs_max_validation.go: Pre-sort safeOutputFieldMapping keys once at init time into sortedSafeOutputMaxFieldNames, replacing the make+sort on every validateSafeOutputsMax call. Saves 1 alloc/op. 5. network_firewall_validation.go: Lazily create ErrorCollector only when a validation error is found, rather than unconditionally at function entry. Saves 1 alloc/op on the common no-error path. Result: BenchmarkValidation 11 allocs/op → 3 allocs/op (-73%) 1256 B/op → 360 B/op (-71%) ~9,000-11,000 ns/op → ~7,000-9,000 ns/op Agent-Logs-Url: https://github.com/github/gh-aw/sessions/ba8f2687-bd5e-4f57-9b89-d2c17f163a31 Co-authored-by: gh-aw-bot <259018956+gh-aw-bot@users.noreply.github.com> --- pkg/workflow/bench_check_test.go | 61 ------------------ pkg/workflow/bench_trace_test.go | 68 --------------------- pkg/workflow/mcp_detection.go | 12 +++- pkg/workflow/network_firewall_validation.go | 32 +++++++--- pkg/workflow/permissions_toolset_data.go | 12 +++- pkg/workflow/permissions_validation.go | 54 ++++++++++++---- pkg/workflow/safe_outputs_max_validation.go | 23 ++++--- 7 files changed, 99 insertions(+), 163 deletions(-) delete mode 100644 pkg/workflow/bench_check_test.go delete mode 100644 pkg/workflow/bench_trace_test.go diff --git a/pkg/workflow/bench_check_test.go b/pkg/workflow/bench_check_test.go deleted file mode 100644 index a1e2c211950..00000000000 --- a/pkg/workflow/bench_check_test.go +++ /dev/null @@ -1,61 +0,0 @@ -//go:build !integration - -package workflow - -import ( -"fmt" -"os" -"path/filepath" -"testing" -) - -func TestValidationState(t *testing.T) { -tmpDir, err := os.MkdirTemp("", "bench-validate") -if err != nil { -t.Fatal(err) -} -defer os.RemoveAll(tmpDir) - -testContent := `--- -on: pull_request -permissions: - contents: read - issues: read - pull-requests: read -engine: copilot -tools: - github: - mode: remote - toolsets: [default] - bash: ["git status"] -strict: true -timeout-minutes: 10 ---- - -# Validation Benchmark - -Test validation performance. -` - -testFile := filepath.Join(tmpDir, "validate.md") -if err := os.WriteFile(testFile, []byte(testContent), 0644); err != nil { -t.Fatal(err) -} - -compiler := NewCompiler(WithNoEmit(true)) -compiler.SetStrictMode(true) -compiler.SetQuiet(true) - -workflowData, err := compiler.ParseWorkflowFile(testFile) -if err != nil { -t.Fatal(err) -} - -fmt.Fprintf(os.Stderr, "SafeOutputs: %v\n", workflowData.SafeOutputs) -fmt.Fprintf(os.Stderr, "NetworkPermissions: %v\n", workflowData.NetworkPermissions) -fmt.Fprintf(os.Stderr, "CachedPermissions: %v\n", workflowData.CachedPermissions != nil) -fmt.Fprintf(os.Stderr, "CachedParsedToolsets: %v\n", workflowData.CachedParsedToolsets) -fmt.Fprintf(os.Stderr, "CachedConcurrencyGroupExprSet: %v\n", workflowData.CachedConcurrencyGroupExprSet) -fmt.Fprintf(os.Stderr, "Concurrency: %q\n", workflowData.Concurrency) -fmt.Fprintf(os.Stderr, "Features: %v\n", workflowData.Features) -} diff --git a/pkg/workflow/bench_trace_test.go b/pkg/workflow/bench_trace_test.go deleted file mode 100644 index 39c9c7920c9..00000000000 --- a/pkg/workflow/bench_trace_test.go +++ /dev/null @@ -1,68 +0,0 @@ -//go:build !integration - -package workflow - -import ( -"os" -"path/filepath" -"runtime" -"testing" -) - -func TestValidationAllocTrace(t *testing.T) { -tmpDir, err := os.MkdirTemp("", "bench-validate") -if err != nil { -t.Fatal(err) -} -defer os.RemoveAll(tmpDir) - -testContent := `--- -on: pull_request -permissions: - contents: read - issues: read - pull-requests: read -engine: copilot -tools: - github: - mode: remote - toolsets: [default] - bash: ["git status"] -strict: true -timeout-minutes: 10 ---- - -# Validation Benchmark - -Test validation performance. -` - -testFile := filepath.Join(tmpDir, "validate.md") -if err := os.WriteFile(testFile, []byte(testContent), 0644); err != nil { -t.Fatal(err) -} - -compiler := NewCompiler(WithNoEmit(true)) -compiler.SetStrictMode(true) -compiler.SetQuiet(true) - -workflowData, err := compiler.ParseWorkflowFile(testFile) -if err != nil { -t.Fatal(err) -} - -// Warm up -if err := compiler.validateWorkflowData(workflowData, testFile); err != nil { -t.Fatal(err) -} - -// Measure allocs for a single call -var m1, m2 runtime.MemStats -runtime.GC() -runtime.ReadMemStats(&m1) -if err := compiler.validateWorkflowData(workflowData, testFile); err != nil { -t.Fatal(err) -} -runtime.ReadMemStats(&m2) -t.Logf("Allocs: %d, Bytes: %d", m2.Mallocs-m1.Mallocs, m2.TotalAlloc-m1.TotalAlloc) -} diff --git a/pkg/workflow/mcp_detection.go b/pkg/workflow/mcp_detection.go index 9fd8fd7dce0..39c438507f9 100644 --- a/pkg/workflow/mcp_detection.go +++ b/pkg/workflow/mcp_detection.go @@ -12,7 +12,9 @@ func HasMCPServers(workflowData *WorkflowData) bool { return false } - mcpDetectionLog.Printf("Checking for MCP servers in workflow '%s': tools=%d", workflowData.Name, len(workflowData.Tools)) + if mcpDetectionLog.Enabled() { + mcpDetectionLog.Printf("Checking for MCP servers in workflow '%s': tools=%d", workflowData.Name, len(workflowData.Tools)) + } // Check for standard MCP tools for toolName, toolValue := range workflowData.Tools { // Skip if the tool is explicitly disabled (set to false) @@ -20,13 +22,17 @@ func HasMCPServers(workflowData *WorkflowData) bool { continue } if toolName == "github" || toolName == "playwright" || toolName == "cache-memory" || toolName == "agentic-workflows" { - mcpDetectionLog.Printf("MCP server detected via built-in tool: %s", toolName) + if mcpDetectionLog.Enabled() { + mcpDetectionLog.Printf("MCP server detected via built-in tool: %s", toolName) + } return true } // Check for custom MCP tools if mcpConfig, ok := toolValue.(map[string]any); ok { if hasMcp, _ := hasMCPConfig(mcpConfig); hasMcp { - mcpDetectionLog.Printf("MCP server detected via custom tool config: %s", toolName) + if mcpDetectionLog.Enabled() { + mcpDetectionLog.Printf("MCP server detected via custom tool config: %s", toolName) + } return true } } diff --git a/pkg/workflow/network_firewall_validation.go b/pkg/workflow/network_firewall_validation.go index b9409f7a9dd..c6e6d34baac 100644 --- a/pkg/workflow/network_firewall_validation.go +++ b/pkg/workflow/network_firewall_validation.go @@ -61,9 +61,13 @@ func (c *Compiler) validateNetworkAllowedDomains(network *NetworkPermissions) er return nil } - networkFirewallValidationLog.Printf("Validating %d network allowed domains", len(network.Allowed)) + if networkFirewallValidationLog.Enabled() { + networkFirewallValidationLog.Printf("Validating %d network allowed domains", len(network.Allowed)) + } - collector := NewErrorCollector(c.failFast) + // collector is lazily initialized on the first validation error to avoid a heap + // allocation on the common path where all domains are valid. + var collector *ErrorCollector for i, domain := range network.Allowed { // "*" means allow all traffic - skip validation @@ -76,17 +80,24 @@ func (c *Compiler) validateNetworkAllowedDomains(network *NetworkPermissions) er if isEcosystemIdentifier(domain) { // Validate it's a known ecosystem identifier using a direct map lookup to avoid allocations if isKnownEcosystemIdentifier(domain) { - networkFirewallValidationLog.Printf("Skipping known ecosystem identifier: %s", domain) + if networkFirewallValidationLog.Enabled() { + networkFirewallValidationLog.Printf("Skipping known ecosystem identifier: %s", domain) + } continue } // Unknown ecosystem identifier - error - networkFirewallValidationLog.Printf("Validation error: unknown ecosystem identifier: %s", domain) + if networkFirewallValidationLog.Enabled() { + networkFirewallValidationLog.Printf("Validation error: unknown ecosystem identifier: %s", domain) + } wrappedErr := fmt.Errorf("network.allowed[%d]: %w", i, NewValidationError( "network.allowed", domain, fmt.Sprintf("'%s' is not a valid ecosystem identifier", domain), "Use a valid ecosystem identifier or a domain name containing a dot (e.g., 'example.com').\n\nValid ecosystem identifiers: "+strings.Join(getValidEcosystemIdentifiers(), ", "), )) + if collector == nil { + collector = NewErrorCollector(c.failFast) + } if returnErr := collector.Add(wrappedErr); returnErr != nil { return returnErr // Fail-fast mode } @@ -95,15 +106,22 @@ func (c *Compiler) validateNetworkAllowedDomains(network *NetworkPermissions) er if err := validateDomainPattern(domain); err != nil { wrappedErr := fmt.Errorf("network.allowed[%d]: %w", i, err) + if collector == nil { + collector = NewErrorCollector(c.failFast) + } if returnErr := collector.Add(wrappedErr); returnErr != nil { return returnErr // Fail-fast mode } } } - if err := collector.Error(); err != nil { - networkFirewallValidationLog.Printf("Network allowed domains validation failed: %v", err) - return err + if collector != nil { + if err := collector.Error(); err != nil { + if networkFirewallValidationLog.Enabled() { + networkFirewallValidationLog.Printf("Network allowed domains validation failed: %v", err) + } + return err + } } networkFirewallValidationLog.Print("Network allowed domains validation passed") diff --git a/pkg/workflow/permissions_toolset_data.go b/pkg/workflow/permissions_toolset_data.go index 60bf7534f75..c68d2e4975e 100644 --- a/pkg/workflow/permissions_toolset_data.go +++ b/pkg/workflow/permissions_toolset_data.go @@ -97,13 +97,17 @@ func (g *GitHubToolConfig) IsReadOnly() bool { // collectRequiredPermissions collects all required permissions for the given toolsets func collectRequiredPermissions(toolsets []string, readOnly bool) map[PermissionScope]PermissionLevel { - permissionsValidationLog.Printf("Collecting required permissions for %d toolsets, read_only=%t", len(toolsets), readOnly) + if permissionsValidationLog.Enabled() { + permissionsValidationLog.Printf("Collecting required permissions for %d toolsets, read_only=%t", len(toolsets), readOnly) + } required := make(map[PermissionScope]PermissionLevel) for _, toolset := range toolsets { perms, exists := toolsetPermissionsMap[toolset] if !exists { - permissionsValidationLog.Printf("Unknown toolset: %s", toolset) + if permissionsValidationLog.Enabled() { + permissionsValidationLog.Printf("Unknown toolset: %s", toolset) + } continue } @@ -112,7 +116,9 @@ func collectRequiredPermissions(toolsets []string, readOnly bool) map[Permission // Skip GitHub App-only permission scopes; these cannot be set via GITHUB_TOKEN // and are validated separately in validateGitHubAppOnlyPermissions. if IsGitHubAppOnlyScope(scope) { - permissionsValidationLog.Printf("Skipping GitHub App-only scope %s for toolset %s", scope, toolset) + if permissionsValidationLog.Enabled() { + permissionsValidationLog.Printf("Skipping GitHub App-only scope %s for toolset %s", scope, toolset) + } continue } // Always require at least read access diff --git a/pkg/workflow/permissions_validation.go b/pkg/workflow/permissions_validation.go index a795bb5e1c4..b2637e5f4e7 100644 --- a/pkg/workflow/permissions_validation.go +++ b/pkg/workflow/permissions_validation.go @@ -37,23 +37,31 @@ type PermissionsValidationResult struct { // Use ValidatePermissions (this function) for general permission validation against GitHub MCP toolsets. // Use ValidateIncludedPermissions (in imports.go) when validating permissions from included/imported workflow files. func ValidatePermissions(permissions *Permissions, githubTool ValidatableTool, parsedToolsets ...[]string) *PermissionsValidationResult { - permissionsValidationLog.Print("Starting permissions validation") - - result := &PermissionsValidationResult{ - MissingPermissions: make(map[PermissionScope]PermissionLevel), - MissingToolsetDetails: make(map[string][]PermissionScope), + if permissionsValidationLog.Enabled() { + permissionsValidationLog.Print("Starting permissions validation") } + // MissingPermissions and MissingToolsetDetails are lazily initialized by + // checkMissingPermissions to avoid heap allocations on the happy path + // (no missing permissions). Callers that read these fields get nil maps, + // which behave like empty maps for reads (len, range, index) but must not + // be written to outside of checkMissingPermissions. + result := &PermissionsValidationResult{} + // If GitHub tool is not configured, no validation needed // Check both for nil interface and nil concrete type if githubTool == nil { - permissionsValidationLog.Print("No GitHub tool configured (nil interface), skipping validation") + if permissionsValidationLog.Enabled() { + permissionsValidationLog.Print("No GitHub tool configured (nil interface), skipping validation") + } return result } // Check if concrete type is nil (interface wrapping nil pointer) if config, ok := githubTool.(*GitHubToolConfig); ok && config == nil { - permissionsValidationLog.Print("No GitHub tool configured (nil concrete type), skipping validation") + if permissionsValidationLog.Enabled() { + permissionsValidationLog.Print("No GitHub tool configured (nil concrete type), skipping validation") + } return result } @@ -64,34 +72,46 @@ func ValidatePermissions(permissions *Permissions, githubTool ValidatableTool, p var toolsets []string if len(parsedToolsets) > 0 && parsedToolsets[0] != nil { toolsets = parsedToolsets[0] - permissionsValidationLog.Printf("Validating with pre-parsed toolsets: %v, read-only: %v", toolsets, readOnly) + if permissionsValidationLog.Enabled() { + permissionsValidationLog.Printf("Validating with pre-parsed toolsets: %v, read-only: %v", toolsets, readOnly) + } } else { toolsetsStr := githubTool.GetToolsets() - permissionsValidationLog.Printf("Validating toolsets: %s, read-only: %v", toolsetsStr, readOnly) + if permissionsValidationLog.Enabled() { + permissionsValidationLog.Printf("Validating toolsets: %s, read-only: %v", toolsetsStr, readOnly) + } toolsets = ParseGitHubToolsets(toolsetsStr) } if len(toolsets) == 0 { - permissionsValidationLog.Print("No toolsets to validate") + if permissionsValidationLog.Enabled() { + permissionsValidationLog.Print("No toolsets to validate") + } return result } // Collect required permissions for all toolsets requiredPermissions := collectRequiredPermissions(toolsets, readOnly) - permissionsValidationLog.Printf("Required permissions: %v", requiredPermissions) + if permissionsValidationLog.Enabled() { + permissionsValidationLog.Printf("Required permissions: %v", requiredPermissions) + } // Check for missing permissions checkMissingPermissions(permissions, requiredPermissions, toolsets, result) result.HasValidationIssues = len(result.MissingPermissions) > 0 - permissionsValidationLog.Printf("Validation complete: hasIssues=%v, missingCount=%d", result.HasValidationIssues, len(result.MissingPermissions)) + if permissionsValidationLog.Enabled() { + permissionsValidationLog.Printf("Validation complete: hasIssues=%v, missingCount=%d", result.HasValidationIssues, len(result.MissingPermissions)) + } return result } // checkMissingPermissions checks if all required permissions are granted func checkMissingPermissions(permissions *Permissions, required map[PermissionScope]PermissionLevel, toolsets []string, result *PermissionsValidationResult) { - permissionsValidationLog.Printf("Checking missing permissions: required_count=%d, toolsets=%v", len(required), toolsets) + if permissionsValidationLog.Enabled() { + permissionsValidationLog.Printf("Checking missing permissions: required_count=%d, toolsets=%v", len(required), toolsets) + } for scope, requiredLevel := range required { grantedLevel, granted := permissions.Get(scope) @@ -103,8 +123,16 @@ func checkMissingPermissions(permissions *Permissions, required map[PermissionSc } if missing { + // Lazily initialize maps on the first missing permission to avoid + // heap allocations on the happy path (all permissions granted). + if result.MissingPermissions == nil { + result.MissingPermissions = make(map[PermissionScope]PermissionLevel) + } result.MissingPermissions[scope] = requiredLevel + if result.MissingToolsetDetails == nil { + result.MissingToolsetDetails = make(map[string][]PermissionScope) + } // Track which toolsets require this permission for _, toolset := range toolsets { perms, exists := toolsetPermissionsMap[toolset] diff --git a/pkg/workflow/safe_outputs_max_validation.go b/pkg/workflow/safe_outputs_max_validation.go index a125d86688c..2fcf224daa4 100644 --- a/pkg/workflow/safe_outputs_max_validation.go +++ b/pkg/workflow/safe_outputs_max_validation.go @@ -10,6 +10,18 @@ import ( var safeOutputsMaxValidationLog = newValidationLogger("safe_outputs_max") +// sortedSafeOutputMaxFieldNames is the pre-sorted list of safeOutputFieldMapping keys used +// by validateSafeOutputsMax for deterministic error reporting. Pre-computing this slice at +// init time avoids a make+sort allocation on every validateSafeOutputsMax call. +var sortedSafeOutputMaxFieldNames = func() []string { + names := make([]string, 0, len(safeOutputFieldMapping)) + for fieldName := range safeOutputFieldMapping { + names = append(names, fieldName) + } + sort.Strings(names) + return names +}() + // isInvalidMaxValue returns true if n is not a valid max field value. // Valid values are positive integers (n > 0) or -1 (unlimited). // Invalid values are 0 and negative integers except -1. @@ -38,14 +50,9 @@ func validateSafeOutputsMax(config *SafeOutputsConfig) error { val := reflect.ValueOf(config).Elem() // Iterate over sorted field names for deterministic error reporting. - sortedFieldNames := make([]string, 0, len(safeOutputFieldMapping)) - for fieldName := range safeOutputFieldMapping { - sortedFieldNames = append(sortedFieldNames, fieldName) - } - sort.Strings(sortedFieldNames) - - // Validate max on all named safe output fields that embed BaseSafeOutputConfig - for _, fieldName := range sortedFieldNames { + // sortedSafeOutputMaxFieldNames is pre-computed at init time to avoid a + // make+sort allocation on every call (performance-critical hot path). + for _, fieldName := range sortedSafeOutputMaxFieldNames { toolName := safeOutputFieldMapping[fieldName] field := val.FieldByName(fieldName) if !field.IsValid() || field.IsNil() {