diff --git a/QuickShell.Core/Services/LaunchCommandSanity.cs b/QuickShell.Core/Services/LaunchCommandSanity.cs index 091172b..5612693 100644 --- a/QuickShell.Core/Services/LaunchCommandSanity.cs +++ b/QuickShell.Core/Services/LaunchCommandSanity.cs @@ -68,17 +68,48 @@ public static bool IsUsableDotNetProjectFileName(string? fileName) private static bool LooksLikeTempProjectReference(string command) { // e.g. dotnet watch --project tmp_serilog_probe.csproj - foreach (var token in command.Split(' ', StringSplitOptions.RemoveEmptyEntries | StringSplitOptions.TrimEntries)) + var span = command.AsSpan(); + var index = 0; + + while (index < span.Length) { - var file = token.Trim('"', '\''); - if (!file.EndsWith(".csproj", StringComparison.OrdinalIgnoreCase) - && !file.EndsWith(".fsproj", StringComparison.OrdinalIgnoreCase) - && !file.EndsWith(".sln", StringComparison.OrdinalIgnoreCase) - && !file.EndsWith(".slnx", StringComparison.OrdinalIgnoreCase)) + // Skip whitespace + while (index < span.Length && span[index] == ' ') + { + index++; + } + + if (index >= span.Length) + { + break; + } + + // Find end of token + var tokenStart = index; + while (index < span.Length && span[index] != ' ') + { + index++; + } + + var tokenSpan = span.Slice(tokenStart, index - tokenStart).Trim(); + if (tokenSpan.IsEmpty) + { + continue; + } + + var fileSpan = tokenSpan.Trim(['"', '\'']); + + // Check extensions using spans to avoid allocations + if (!fileSpan.EndsWith(".csproj", StringComparison.OrdinalIgnoreCase) + && !fileSpan.EndsWith(".fsproj", StringComparison.OrdinalIgnoreCase) + && !fileSpan.EndsWith(".sln", StringComparison.OrdinalIgnoreCase) + && !fileSpan.EndsWith(".slnx", StringComparison.OrdinalIgnoreCase)) { continue; } + // Fall back to string allocation only when necessary to call IsUsableDotNetProjectFileName + var file = fileSpan.ToString(); if (!IsUsableDotNetProjectFileName(file)) { return true; diff --git a/QuickShell.Core/Services/WorkspaceHealthCheck.cs b/QuickShell.Core/Services/WorkspaceHealthCheck.cs index 1e91aea..efe08ac 100644 --- a/QuickShell.Core/Services/WorkspaceHealthCheck.cs +++ b/QuickShell.Core/Services/WorkspaceHealthCheck.cs @@ -562,7 +562,10 @@ private static IEnumerable DetectPorts(TerminalShortcut shortcut) return endQuote > 1 ? Path.GetFileName(trimmed[1..endQuote]) : null; } - var token = trimmed.Split([' ', '\t'], StringSplitOptions.RemoveEmptyEntries).FirstOrDefault(); + // Bolt: Performance optimization - use IndexOfAny to avoid string array allocation from Split + var spaceIndex = trimmed.AsSpan().IndexOfAny(' ', '\t'); + var token = spaceIndex >= 0 ? trimmed[..spaceIndex] : trimmed; + if (string.IsNullOrWhiteSpace(token)) { return null;