From a2cc7249ebf0f2517907531e8747a947a37b1d3d Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Tue, 26 Aug 2025 16:57:33 +0000 Subject: [PATCH 1/3] Initial plan From 94ab4b39c947abe1e63a5dfe2f8e61e50b79ddd1 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Tue, 26 Aug 2025 17:04:53 +0000 Subject: [PATCH 2/3] Update to Zig 0.14.1 and modernize code patterns Co-authored-by: 0xrinegade <101195284+0xrinegade@users.noreply.github.com> --- README.md | 2 +- package.json | 4 ++-- src/index.ts | 42 ++++++++++++++++++++++++++++++++++-------- 3 files changed, 37 insertions(+), 11 deletions(-) diff --git a/README.md b/README.md index afcb3de..745ccfc 100644 --- a/README.md +++ b/README.md @@ -193,7 +193,7 @@ const result = await useMcpTool("zig", "get_recommendations", { var i: u32 = 0; while (true) { if (i >= 100) break; - try list.append(@intCast(u8, i)); + try list.append(@intCast(i)); i += 1; } } diff --git a/package.json b/package.json index a80a7b6..ad86a4b 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "zig-mcp-server", - "version": "0.1.0", - "description": "zig ai 10x dev assistant", + "version": "0.2.0", + "description": "zig ai 10x dev assistant - updated for Zig 0.14.1", "private": true, "type": "module", "bin": { diff --git a/src/index.ts b/src/index.ts index 453b612..2cad4a7 100644 --- a/src/index.ts +++ b/src/index.ts @@ -18,7 +18,7 @@ class ZigServer { this.server = new Server( { name: 'zig-mcp-server', - version: '0.1.0', + version: '0.2.0', }, { capabilities: { @@ -230,8 +230,8 @@ class ZigServer { private async fetchZigDocs(section: 'language' | 'std'): Promise { try { - // Fetch from Zig's official documentation - const response = await axios.get(`https://ziglang.org/documentation/master/${section === 'language' ? 'index' : 'std'}.html`); + // Fetch from Zig's official documentation for version 0.14.1 + const response = await axios.get(`https://ziglang.org/documentation/0.14.1/${section === 'language' ? 'index' : 'std'}.html`); return response.data; } catch (error) { const errorMessage = error instanceof Error ? error.message : 'Unknown error'; @@ -344,19 +344,25 @@ ${analysis.allocations} private analyzeMemoryUsage(code: string): string { const patterns = { - heapAlloc: /std\.(ArrayList|StringHashMap|AutoHashMap)/g, + heapAlloc: /std\.(ArrayList|StringHashMap|AutoHashMap|HashMap)/g, stackAlloc: /var\s+\w+\s*:\s*\[(\d+)\]/g, - slices: /\[\](?:u8|i32|f64)/g, + slices: /\[\](?:u8|i32|f64|usize|isize)/g, + multiArrayList: /std\.MultiArrayList/g, + boundedArray: /std\.BoundedArray/g, }; const heapAllocs = (code.match(patterns.heapAlloc) || []).length; const stackAllocs = (code.match(patterns.stackAlloc) || []).length; const sliceUsage = (code.match(patterns.slices) || []).length; + const multiArrayLists = (code.match(patterns.multiArrayList) || []).length; + const boundedArrays = (code.match(patterns.boundedArray) || []).length; return ` - Heap Allocations: ${heapAllocs} detected - Stack Allocations: ${stackAllocs} detected - Slice Usage: ${sliceUsage} instances +- MultiArrayList: ${multiArrayLists} instances +- BoundedArray: ${boundedArrays} instances - Memory Profile: ${heapAllocs > stackAllocs ? 'Heap-heavy' : 'Stack-optimized'} `.trim(); } @@ -515,7 +521,12 @@ pub const MyStruct = struct { } pub fn deinit(self: *MyStruct) void { - // Cleanup + // Cleanup allocated resources + _ = self; // suppress unused variable warning + } + + pub fn getData(self: *const MyStruct) []const u8 { + return self.data; } }; `.trim(); @@ -530,6 +541,7 @@ pub const MyStruct = struct { ${fnHeader} { ${requirements.errorHandling ? 'if (input.len == 0) return Error.InvalidInput;' : ''} // Function implementation + _ = input; // suppress unused parameter warning if not used } `.trim(); } @@ -616,6 +628,14 @@ ${analysis.performance} if (code.includes('std.fmt.allocPrint')) { patterns.push('- Consider using formatters or bufPrint when possible'); } + + // Check for outdated Zig syntax (pre-0.11) + if (code.match(/@intCast\(\s*\w+\s*,/)) { + patterns.push('- Update @intCast syntax: use @intCast(value) instead of @intCast(Type, value)'); + } + if (code.match(/@floatCast\(\s*\w+\s*,/)) { + patterns.push('- Update @floatCast syntax: use @floatCast(value) instead of @floatCast(Type, value)'); + } return patterns.length > 0 ? patterns.join('\n') : '- No significant pattern issues detected'; } @@ -662,16 +682,22 @@ ${analysis.performance} recommendations.push('- Use comptime when possible'); recommendations.push('- Consider using packed structs for memory optimization'); recommendations.push('- Implement custom allocators for specific use cases'); + recommendations.push('- Use @inline for small hot functions'); + recommendations.push('- Consider using @Vector for SIMD operations'); } if (prompt.toLowerCase().includes('safety')) { recommendations.push('- Add bounds checking for array access'); - recommendations.push('- Use explicit error handling'); - recommendations.push('- Implement proper resource cleanup'); + recommendations.push('- Use explicit error handling with try/catch'); + recommendations.push('- Implement proper resource cleanup with defer'); + recommendations.push('- Use const where possible to prevent mutations'); + recommendations.push('- Avoid undefined behavior with proper initialization'); } if (prompt.toLowerCase().includes('maintainability')) { recommendations.push('- Add comprehensive documentation'); recommendations.push('- Break down complex functions'); recommendations.push('- Use meaningful variable names'); + recommendations.push('- Organize code into modules and namespaces'); + recommendations.push('- Write unit tests for public functions'); } return recommendations.join('\n'); From fe473cc5be7106963d4227cc0884b6f78455d923 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sat, 30 Aug 2025 06:25:55 +0000 Subject: [PATCH 3/3] Add comprehensive Zig build optimizations and performance tips - Enhanced optimize_code() with extensive build flags and SIMD optimizations - Expanded analyzePerformance() with modern Zig features and vector operations - Added comprehensive memory analysis including alignment and allocator patterns - Enhanced time complexity analysis with SIMD and parallelization detection - Added detailed build configuration recommendations for all optimization levels - Included compiler flags for performance tuning (vectorization, CPU-specific opts) - Added SIMD/vector operation recommendations and builtin function suggestions - Enhanced allocator analysis with modern Zig allocator types and patterns Co-authored-by: 0xrinegade <101195284+0xrinegade@users.noreply.github.com> --- src/index.ts | 348 ++++++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 319 insertions(+), 29 deletions(-) diff --git a/src/index.ts b/src/index.ts index 2cad4a7..51638f2 100644 --- a/src/index.ts +++ b/src/index.ts @@ -274,9 +274,10 @@ class ZigServer { // Analyze code for optimization opportunities const optimizations = []; - // Check for common patterns that can be optimized + // Memory and allocation optimizations if (code.includes('std.ArrayList')) { optimizations.push('Consider pre-allocating ArrayList capacity if size is known'); + optimizations.push('Use ArrayListUnmanaged for better cache locality and reduced indirection'); } if (code.includes('std.fmt.allocPrint')) { optimizations.push('Consider using std.fmt.bufPrint for stack allocation when possible'); @@ -284,23 +285,74 @@ class ZigServer { if (code.match(/while\s*\(true\)/)) { optimizations.push('Consider using continue/break instead of while(true)'); } + + // SIMD and vectorization opportunities + if (code.match(/for\s*\([^)]*\)\s*\|[^|]*\|\s*{[^}]*[+\-*/][^}]*}/)) { + optimizations.push('Consider using @Vector for SIMD operations on numeric arrays'); + } + if (code.includes('[]f32') || code.includes('[]f64')) { + optimizations.push('Float arrays can benefit from vectorized operations using @Vector'); + } + + // Comptime optimizations + if (code.match(/const\s+\w+\s*=\s*\d+/)) { + optimizations.push('Move constant calculations to comptime using comptime var'); + } + if (code.includes('std.crypto') || code.includes('std.hash')) { + optimizations.push('Consider comptime evaluation for constant hash/crypto operations'); + } + + // Memory layout optimizations + if (code.includes('struct {')) { + optimizations.push('Consider using packed struct for memory efficiency if appropriate'); + optimizations.push('Order struct fields by size (largest first) for optimal packing'); + } + + // Function call optimizations + if (code.match(/fn\s+\w+[^{]*{[^}]{1,50}}/)) { + optimizations.push('Consider @inline for small hot functions (under ~50 lines)'); + } + if (code.includes('std.math')) { + optimizations.push('Use builtin math functions like @sqrt, @sin, @cos for better performance'); + } + + // Modern Zig collection optimizations + if (code.includes('std.HashMap')) { + optimizations.push('Consider ArrayHashMap for better cache locality with small datasets'); + optimizations.push('Use HashMap.initWithContext for custom hash/equality functions'); + } + if (code.includes('std.MultiArrayList')) { + optimizations.push('MultiArrayList provides better cache efficiency for struct-of-arrays pattern'); + } // Build mode specific optimizations const buildModeOpts = { - Debug: [], + Debug: [ + 'Enable debug info with -fdebug-info', + 'Use -fsanitize=address for memory debugging', + 'Consider --verbose-llvm-ir for LLVM optimization inspection', + ], ReleaseSafe: [ - 'Runtime safety checks enabled', - 'Optimizations enabled', + 'Runtime safety checks enabled (-OReleaseSafe)', + 'LLVM -O2 optimizations enabled', + 'Use -flto for link-time optimization', + 'Enable -mcpu=native for target-specific optimizations', ], ReleaseFast: [ - 'Runtime safety checks disabled', - 'Maximum performance optimizations', - 'Consider adding debug assertions for critical paths', + 'Runtime safety checks disabled (-OReleaseFast)', + 'Maximum LLVM -O3 optimizations', + 'Use -fstrip for smaller binaries', + 'Enable -march=native for maximum target optimization', + 'Consider -funroll-loops for loop-heavy code', + 'Use -fno-stack-check for maximum performance', ], ReleaseSmall: [ - 'Size optimizations enabled', - 'Consider removing debug information', - 'Minimize template instantiations', + 'Size optimizations enabled (-OReleaseSmall)', + 'LLVM -Os optimization for size', + 'Use -fstrip to remove debug symbols', + 'Enable -flto for dead code elimination', + 'Consider -ffunction-sections -fdata-sections for better linking', + 'Use @setRuntimeSafety(false) in hot paths', ], }; @@ -309,12 +361,26 @@ class ZigServer { return ` Optimization Analysis for ${level}: -General Optimizations: +General Code Optimizations: ${optimizations.map(opt => `- ${opt}`).join('\n')} -Build Mode Specific: +Build Configuration for ${level}: ${modeSpecificOpts.map(opt => `- ${opt}`).join('\n')} +Advanced Build Tips: +- Use 'zig build-exe -O${level}' for optimized builds +- Set target with '--target x86_64-linux-gnu' for cross-compilation +- Add '-mcpu=native' for CPU-specific optimizations +- Use '-flto' for link-time optimization (longer compile time, better performance) +- Enable '-fstrip' to reduce binary size in release builds + +Compiler Flags for Performance: +- '-funroll-loops': Unroll loops for better performance +- '-fvectorize': Enable auto-vectorization +- '-march=native': Use all CPU features available +- '-mtune=native': Optimize for specific CPU model +- '-fomit-frame-pointer': Remove frame pointer for register allocation + Optimized Code: ${code} `.trim(); @@ -346,9 +412,15 @@ ${analysis.allocations} const patterns = { heapAlloc: /std\.(ArrayList|StringHashMap|AutoHashMap|HashMap)/g, stackAlloc: /var\s+\w+\s*:\s*\[(\d+)\]/g, - slices: /\[\](?:u8|i32|f64|usize|isize)/g, + slices: /\[\](?:u8|i32|f64|usize|isize|f32|i64|u32|u64|i16|u16)/g, multiArrayList: /std\.MultiArrayList/g, boundedArray: /std\.BoundedArray/g, + vectorTypes: /@Vector\(\s*\d+\s*,/g, + packedStruct: /packed\s+struct/g, + alignedTypes: /@alignOf|align\(\d+\)/g, + allocators: /std\.heap\.(ArenaAllocator|FixedBufferAllocator|GeneralPurposeAllocator|page_allocator)/g, + arrayListUnmanaged: /ArrayListUnmanaged/g, + simdAlignment: /@alignOf\(.*@Vector/g, }; const heapAllocs = (code.match(patterns.heapAlloc) || []).length; @@ -356,14 +428,41 @@ ${analysis.allocations} const sliceUsage = (code.match(patterns.slices) || []).length; const multiArrayLists = (code.match(patterns.multiArrayList) || []).length; const boundedArrays = (code.match(patterns.boundedArray) || []).length; + const vectorTypes = (code.match(patterns.vectorTypes) || []).length; + const packedStructs = (code.match(patterns.packedStruct) || []).length; + const alignedTypes = (code.match(patterns.alignedTypes) || []).length; + const allocators = (code.match(patterns.allocators) || []).length; + const arrayListUnmanaged = (code.match(patterns.arrayListUnmanaged) || []).length; + const simdAlignment = (code.match(patterns.simdAlignment) || []).length; + + const recommendations = []; + + if (heapAllocs > arrayListUnmanaged && heapAllocs > 0) { + recommendations.push('Consider ArrayListUnmanaged for reduced pointer indirection'); + } + if (vectorTypes > 0 && simdAlignment === 0) { + recommendations.push('Ensure SIMD vectors are properly aligned for optimal performance'); + } + if (sliceUsage > 0 && multiArrayLists === 0 && heapAllocs > 2) { + recommendations.push('Consider MultiArrayList for better cache locality with multiple arrays'); + } + if (stackAllocs === 0 && boundedArrays === 0 && heapAllocs > 0) { + recommendations.push('Consider BoundedArray for small, stack-allocated dynamic arrays'); + } return ` - Heap Allocations: ${heapAllocs} detected -- Stack Allocations: ${stackAllocs} detected +- Stack Allocations: ${stackAllocs} detected - Slice Usage: ${sliceUsage} instances -- MultiArrayList: ${multiArrayLists} instances -- BoundedArray: ${boundedArrays} instances +- MultiArrayList: ${multiArrayLists} instances (SoA pattern for cache efficiency) +- BoundedArray: ${boundedArrays} instances (stack-allocated dynamic arrays) +- Vector Types: ${vectorTypes} instances (SIMD support) +- Packed Structs: ${packedStructs} instances (memory optimization) +- Aligned Types: ${alignedTypes} instances (alignment optimization) +- Custom Allocators: ${allocators} instances +- ArrayListUnmanaged: ${arrayListUnmanaged} instances (reduced overhead) - Memory Profile: ${heapAllocs > stackAllocs ? 'Heap-heavy' : 'Stack-optimized'} +${recommendations.length > 0 ? '\nRecommendations:\n' + recommendations.map(r => `- ${r}`).join('\n') : ''} `.trim(); } @@ -372,22 +471,45 @@ ${analysis.allocations} loops: /(?:while|for)\s*\(/g, nestedLoops: /(?:while|for)[^{]*\{[^}]*(?:while|for)/g, recursion: /fn\s+\w+[^{]*\{[^}]*\w+\s*\([^)]*\)/g, + vectorOperations: /@Vector\([^)]*\)[^;]*[+\-*/]/g, + builtinMath: /@(?:sqrt|sin|cos|exp|log|pow)\s*\(/g, + memoryOps: /@(?:memcpy|memset|memmove)\s*\(/g, + simdReductions: /@reduce\s*\(/g, + parallelizable: /std\.Thread|std\.atomic/g, }; const loops = (code.match(patterns.loops) || []).length; const nestedLoops = (code.match(patterns.nestedLoops) || []).length; const recursion = (code.match(patterns.recursion) || []).length; + const vectorOps = (code.match(patterns.vectorOperations) || []).length; + const builtinMath = (code.match(patterns.builtinMath) || []).length; + const memoryOps = (code.match(patterns.memoryOps) || []).length; + const simdReductions = (code.match(patterns.simdReductions) || []).length; + const parallelizable = (code.match(patterns.parallelizable) || []).length; let complexity = 'O(1)'; if (nestedLoops > 0) complexity = 'O(n²)'; else if (loops > 0) complexity = 'O(n)'; if (recursion > 0) complexity += ' with recursive calls'; + + const optimizationNotes = []; + if (vectorOps > 0) optimizationNotes.push('SIMD vectorization detected'); + if (builtinMath > 0) optimizationNotes.push('Optimized builtin math functions used'); + if (memoryOps > 0) optimizationNotes.push('Optimized memory operations detected'); + if (simdReductions > 0) optimizationNotes.push('Vector reductions for parallel computation'); + if (parallelizable > 0) optimizationNotes.push('Potential for parallel execution'); return ` - Estimated Complexity: ${complexity} - Loop Count: ${loops} - Nested Loops: ${nestedLoops} - Recursive Patterns: ${recursion} detected +- Vector Operations: ${vectorOps} (SIMD optimization opportunities) +- Builtin Math Functions: ${builtinMath} (hardware-optimized) +- Memory Operations: ${memoryOps} (optimized bulk operations) +- SIMD Reductions: ${simdReductions} (parallel reductions) +- Threading/Atomic Operations: ${parallelizable} (parallelization potential) +${optimizationNotes.length > 0 ? '\nOptimization Notes:\n' + optimizationNotes.map(note => `- ${note}`).join('\n') : ''} `.trim(); } @@ -396,25 +518,69 @@ ${analysis.allocations} comptime: /comptime\s/g, arena: /std\.heap\.ArenaAllocator/g, fixedBuf: /std\.heap\.FixedBufferAllocator/g, + gpa: /std\.heap\.GeneralPurposeAllocator/g, + pageAlloc: /std\.heap\.page_allocator/g, + stackFallback: /std\.heap\.StackFallbackAllocator/g, + alignedAlloc: /alignedAlloc|@alignOf/g, + defer: /defer\s/g, + errdefer: /errdefer\s/g, + embedFile: /@embedFile\s*\(/g, + comptimeEval: /comptime\s+{[^}]+}/g, }; const comptimeUsage = (code.match(patterns.comptime) || []).length; const arenaAlloc = (code.match(patterns.arena) || []).length; const fixedBufAlloc = (code.match(patterns.fixedBuf) || []).length; + const gpaAlloc = (code.match(patterns.gpa) || []).length; + const pageAlloc = (code.match(patterns.pageAlloc) || []).length; + const stackFallback = (code.match(patterns.stackFallback) || []).length; + const alignedAllocs = (code.match(patterns.alignedAlloc) || []).length; + const deferUsage = (code.match(patterns.defer) || []).length; + const errdeferUsage = (code.match(patterns.errdefer) || []).length; + const embedFileUsage = (code.match(patterns.embedFile) || []).length; + const comptimeEvals = (code.match(patterns.comptimeEval) || []).length; + + const allocatorRecommendations = []; + if (arenaAlloc === 0 && fixedBufAlloc === 0 && gpaAlloc === 0) { + allocatorRecommendations.push('Consider using specialized allocators for better performance'); + } + if (alignedAllocs > 0) { + allocatorRecommendations.push('SIMD-aligned allocations detected - good for vectorization'); + } + if (deferUsage === 0 && (arenaAlloc > 0 || fixedBufAlloc > 0)) { + allocatorRecommendations.push('Add defer statements for proper cleanup'); + } + if (embedFileUsage > 0) { + allocatorRecommendations.push('Compile-time file embedding reduces runtime I/O'); + } return ` -- Comptime Evaluations: ${comptimeUsage} -- Arena Allocators: ${arenaAlloc} -- Fixed Buffer Allocators: ${fixedBufAlloc} -- Allocation Strategy: ${this.determineAllocStrategy(arenaAlloc, fixedBufAlloc)} +- Comptime Evaluations: ${comptimeUsage} (compile-time optimization) +- Comptime Blocks: ${comptimeEvals} (complex compile-time evaluation) +- Arena Allocators: ${arenaAlloc} (batch allocation/cleanup) +- Fixed Buffer Allocators: ${fixedBufAlloc} (stack-based allocation) +- General Purpose Allocators: ${gpaAlloc} (debugging/development) +- Page Allocators: ${pageAlloc} (large allocations) +- Stack Fallback Allocators: ${stackFallback} (hybrid stack/heap) +- Aligned Allocations: ${alignedAllocs} (SIMD optimization) +- Defer Statements: ${deferUsage} (cleanup automation) +- Errdefer Statements: ${errdeferUsage} (error cleanup) +- Embedded Files: ${embedFileUsage} (compile-time resources) +- Allocation Strategy: ${this.determineAllocStrategy(arenaAlloc, fixedBufAlloc, gpaAlloc, pageAlloc)} +${allocatorRecommendations.length > 0 ? '\nAllocator Recommendations:\n' + allocatorRecommendations.map(r => `- ${r}`).join('\n') : ''} `.trim(); } - private determineAllocStrategy(arenaCount: number, fixedBufCount: number): string { - if (arenaCount > 0 && fixedBufCount > 0) return 'Mixed allocation strategy'; - if (arenaCount > 0) return 'Arena-based allocation'; - if (fixedBufCount > 0) return 'Fixed buffer allocation'; - return 'Default allocator usage'; + private determineAllocStrategy(arenaCount: number, fixedBufCount: number, gpaCount: number = 0, pageCount: number = 0): string { + const allocTypes = []; + if (arenaCount > 0) allocTypes.push('Arena'); + if (fixedBufCount > 0) allocTypes.push('FixedBuffer'); + if (gpaCount > 0) allocTypes.push('GeneralPurpose'); + if (pageCount > 0) allocTypes.push('Page'); + + if (allocTypes.length === 0) return 'Default allocator usage'; + if (allocTypes.length === 1) return `${allocTypes[0]}-based allocation`; + return `Mixed allocation strategy (${allocTypes.join(', ')})`; } private async generateCode(prompt: string, context?: string): Promise { @@ -660,18 +826,85 @@ ${analysis.performance} private analyzePerformance(code: string): string { const performance = []; - // Check performance patterns + // Memory allocation patterns if (code.includes('std.ArrayList') && !code.match(/initCapacity/)) { - performance.push('- Consider pre-allocating ArrayList capacity'); + performance.push('- Consider pre-allocating ArrayList capacity with initCapacity()'); + } + if (code.includes('std.ArrayList') && !code.includes('ArrayListUnmanaged')) { + performance.push('- Consider ArrayListUnmanaged for reduced pointer indirection'); } + + // Arithmetic and computation optimizations if (code.match(/\+\s*\d+\s*\+/)) { performance.push('- Use comptime for constant expressions'); } if (code.includes('std.crypto')) { performance.push('- Consider using batch processing for crypto operations'); } + if (code.match(/\bmul\b|\bdiv\b|\bmod\b/)) { + performance.push('- Consider using bit operations for power-of-2 operations'); + } + + // SIMD and vectorization opportunities + if (code.includes('[]f32') || code.includes('[]f64') || code.includes('[]i32')) { + performance.push('- Consider @Vector for SIMD operations on numeric arrays'); + performance.push('- Use @reduce() for vector reduction operations'); + } + if (code.match(/for\s*\([^)]*\)\s*\|[^|]*\|\s*{[^}]*[+\-*/]/)) { + performance.push('- Loop with arithmetic operations can benefit from vectorization'); + } + + // Memory layout and access patterns + if (code.includes('struct {')) { + performance.push('- Order struct fields by alignment (largest first) for optimal packing'); + performance.push('- Consider packed struct for memory-constrained scenarios'); + } + if (code.includes('[][]')) { + performance.push('- Consider MultiArrayList for better cache locality (AoS → SoA)'); + } + + // Function call optimizations + if (code.match(/fn\s+\w+[^{]*{[^}]{1,100}}/)) { + performance.push('- Consider @inline for small, frequently-called functions'); + } + if (code.includes('@call')) { + performance.push('- Use @call(.always_inline, ...) for guaranteed inlining'); + } + + // Builtin functions for performance + if (code.includes('std.math.sqrt')) { + performance.push('- Use @sqrt() builtin instead of std.math.sqrt for better performance'); + } + if (code.includes('std.math.sin') || code.includes('std.math.cos')) { + performance.push('- Use @sin()/@cos() builtins for better performance'); + } + if (code.includes('std.mem.copy') || code.includes('std.mem.set')) { + performance.push('- Use @memcpy()/@memset() builtins for optimized memory operations'); + } + + // Modern Zig collections and patterns + if (code.includes('std.HashMap') && !code.includes('ArrayHashMap')) { + performance.push('- Consider ArrayHashMap for better cache locality with small datasets'); + } + if (code.includes('std.BoundedArray')) { + performance.push('- BoundedArray provides stack allocation with dynamic sizing'); + } + + // Compile-time optimizations + if (code.match(/const\s+\w+\s*=.*std\.(hash|crypto)/)) { + performance.push('- Move hash/crypto constants to comptime evaluation'); + } + if (code.includes('switch (')) { + performance.push('- Ensure switch cases are comptime-known when possible'); + } + + // Platform-specific optimizations + if (code.includes('std.Thread') || code.includes('std.atomic')) { + performance.push('- Consider target CPU cache line size for atomic operations'); + performance.push('- Use std.atomic.Ordering for fine-grained memory ordering control'); + } - return performance.length > 0 ? performance.join('\n') : '- No immediate performance concerns'; + return performance.length > 0 ? performance.join('\n') : '- No immediate performance concerns detected'; } private getSpecificRecommendations(code: string, prompt: string): string { @@ -679,25 +912,82 @@ ${analysis.performance} // Add context-specific recommendations based on the prompt if (prompt.toLowerCase().includes('performance')) { - recommendations.push('- Use comptime when possible'); + recommendations.push('- Use comptime when possible for compile-time evaluation'); recommendations.push('- Consider using packed structs for memory optimization'); recommendations.push('- Implement custom allocators for specific use cases'); recommendations.push('- Use @inline for small hot functions'); recommendations.push('- Consider using @Vector for SIMD operations'); + recommendations.push('- Use @prefetch() to hint cache warming for pointer access'); + recommendations.push('- Leverage @optimizeFor(.ReleaseFast) for critical functions'); + recommendations.push('- Use @setRuntimeSafety(false) in performance-critical paths'); + recommendations.push('- Consider ArrayListUnmanaged for reduced indirection overhead'); + recommendations.push('- Use MultiArrayList for better cache locality (Structure of Arrays)'); + recommendations.push('- Leverage @reduce() for efficient vector reductions'); + recommendations.push('- Use builtin functions (@sqrt, @sin, @cos) instead of std.math'); + recommendations.push('- Consider @embedFile() for compile-time resource inclusion'); + recommendations.push('- Use @bitCast() instead of @ptrCast() when possible for better optimization'); + recommendations.push('- Leverage @splat() for vector initialization'); } + + if (prompt.toLowerCase().includes('build') || prompt.toLowerCase().includes('optimization')) { + recommendations.push('- Use -OReleaseFast for maximum runtime performance'); + recommendations.push('- Enable -mcpu=native for target-specific CPU optimizations'); + recommendations.push('- Use -flto for link-time optimization and dead code elimination'); + recommendations.push('- Add -march=native to utilize all available CPU features'); + recommendations.push('- Use -fstrip to reduce binary size in production builds'); + recommendations.push('- Enable -funroll-loops for loop-heavy computations'); + recommendations.push('- Use -fomit-frame-pointer for additional register availability'); + recommendations.push('- Consider -mtune=native for CPU-specific tuning'); + recommendations.push('- Use --verbose-llvm-ir to inspect LLVM optimization passes'); + recommendations.push('- Enable -ffunction-sections -fdata-sections for better dead code elimination'); + recommendations.push('- Use -fsanitize=address in debug builds for memory error detection'); + recommendations.push('- Consider cross-compilation with --target for specific architectures'); + recommendations.push('- Use zig build-exe -OReleaseSmall for size-optimized builds'); + recommendations.push('- Leverage -femit-llvm-ir to analyze generated LLVM code'); + } + + if (prompt.toLowerCase().includes('memory')) { + recommendations.push('- Use ArenaAllocator for batch allocations with single cleanup'); + recommendations.push('- Consider FixedBufferAllocator for stack-based allocation'); + recommendations.push('- Use std.heap.page_allocator for large, long-lived allocations'); + recommendations.push('- Implement GeneralPurposeAllocator for debugging memory issues'); + recommendations.push('- Use BoundedArray for stack-allocated dynamic arrays'); + recommendations.push('- Consider @alignOf() and @sizeOf() for memory layout optimization'); + recommendations.push('- Use @memcpy() and @memset() builtins for optimized memory operations'); + recommendations.push('- Leverage packed structs for memory-constrained environments'); + recommendations.push('- Use std.mem.Allocator.alignedAlloc() for SIMD-aligned allocations'); + } + + if (prompt.toLowerCase().includes('simd') || prompt.toLowerCase().includes('vector')) { + recommendations.push('- Use @Vector(len, T) for explicit SIMD programming'); + recommendations.push('- Leverage @splat() to broadcast scalars to vectors'); + recommendations.push('- Use @reduce() for vector reductions (sum, min, max, etc.)'); + recommendations.push('- Consider @shuffle() for vector lane rearrangement'); + recommendations.push('- Use @select() for conditional vector operations'); + recommendations.push('- Ensure data alignment with @alignOf() for optimal SIMD performance'); + recommendations.push('- Use vector length that matches target CPU SIMD width'); + recommendations.push('- Consider loop unrolling for better vectorization opportunities'); + } + if (prompt.toLowerCase().includes('safety')) { recommendations.push('- Add bounds checking for array access'); recommendations.push('- Use explicit error handling with try/catch'); recommendations.push('- Implement proper resource cleanup with defer'); recommendations.push('- Use const where possible to prevent mutations'); recommendations.push('- Avoid undefined behavior with proper initialization'); + recommendations.push('- Use @setRuntimeSafety(true) in debug builds'); + recommendations.push('- Leverage optional types (?T) instead of null pointers'); + recommendations.push('- Use tagged unions for type-safe variant types'); } + if (prompt.toLowerCase().includes('maintainability')) { recommendations.push('- Add comprehensive documentation'); recommendations.push('- Break down complex functions'); recommendations.push('- Use meaningful variable names'); recommendations.push('- Organize code into modules and namespaces'); recommendations.push('- Write unit tests for public functions'); + recommendations.push('- Use comptime for compile-time validation'); + recommendations.push('- Leverage Zig\'s type system for self-documenting code'); } return recommendations.join('\n');