using System.Collections.Generic;
using KGySoft.CoreLibraries;
using KGySoft.Diagnostics;
private const string text = @"
ALLUSERSPROFILE=C:\ProgramData
ComSpec=C:\WINDOWS\system32\cmd.exe
Path=C:\Windows\system32;C:\Windows\System32\Wbem;C:\Windows\System32\WindowsPowerShell\v1.0\;C:\Windows\System32\OpenSSH\;C:\Program Files\dotnet\;%USERPROFILE%\AppData\Local\Microsoft\WindowsApps
PATHEXT=.COM;.EXE;.BAT;.CMD;.VBS;.VBE;.JS;.JSE;.WSF;.WSH;.MSC
CommonProgramFiles=C:\Program Files\Common Files
CommonProgramFiles(x86)=C:\Program Files (x86)\Common Files
CommonProgramW6432=C:\Program Files\Common Files
DriverData=C:\Windows\System32\Drivers\DriverData
ProgramData=C:\ProgramData
ProgramFiles=C:\Program Files
ProgramFiles(x86)=C:\Program Files (x86)
ProgramW6432=C:\Program Files
PSModulePath=C:\Program Files\WindowsPowerShell\Modules;C:\WINDOWS\system32\WindowsPowerShell\v1.0\Modules
public static string[] ByString(string content, string key)
string[] nonEmptyLines = content.Split(new[] { Environment.NewLine }, StringSplitOptions.RemoveEmptyEntries);
foreach (string line in nonEmptyLines)
string[] keyValues = line.Split(new[] { '=' }, count: 2);
if (keyValues[0].TrimStart() == key)
return keyValues[1].Split(';');
public static IList<StringSegment> ByStringSegment(string content, string key)
IList<StringSegment> nonEmptyLines = content.AsSegment().Split(Environment.NewLine, StringSegmentSplitOptions.RemoveEmptyEntries);
foreach (StringSegment line in nonEmptyLines)
IList<StringSegment> keyValues = line.Split('=', maxLength: 2);
if (keyValues[0].TrimStart() == key)
return keyValues[1].Split(';');
public static IList<StringSegment> ByStringSegmentAlternative(string content, string key)
StringSegment rest = content;
StringSegment line = rest.ReadLine();
IList<StringSegment> keyValues = line.Split('=', maxLength: 2);
if (keyValues[0].TrimStart() == key)
return keyValues[1].Split(';');
public static void Main()
const string key = "Path";
DumpValues(ByString(text, key));
DumpValues(ByStringSegment(text, key));
DumpValues(ByStringSegmentAlternative(text, key));
new PerformanceTest { Iterations = 10_000, CpuAffinity = null }
.AddCase(() => ByString(text, key), "String.Split+Trim")
.AddCase(() => ByStringSegment(text, key), "StringSegment.Split+Trim")
.AddCase(() => ByStringSegmentAlternative(text, key), "StringSegmentExtensions.ReadLine+StringSegment.Split+Trim")
.DumpResults(Console.Out);
private static void DumpValues<T>(IEnumerable<T> values) => Console.WriteLine(values.Join(", "));