134 lines
3.6 KiB
C#
134 lines
3.6 KiB
C#
using System.Text.RegularExpressions;
|
|
using BenchmarkDotNet.Attributes;
|
|
using BenchmarkDotNet.Running;
|
|
|
|
BenchmarkRunner.Run<LineCountBenchmarks>();
|
|
|
|
[SimpleJob, MemoryDiagnoser(false)]
|
|
public class LineCountBenchmarks
|
|
{
|
|
private readonly Options _options = new()
|
|
{
|
|
Path = Environment.GetEnvironmentVariable("TEST_PATH") ?? ".",
|
|
Pattern = "\\.cs$"
|
|
};
|
|
|
|
[Benchmark]
|
|
public async Task<int> CountLinesAsync()
|
|
{
|
|
var regex = new Regex(_options.Pattern, RegexOptions.Compiled);
|
|
var path = Path.GetFullPath(_options.Path);
|
|
var searchOption = _options.Recurse ? SearchOption.AllDirectories : SearchOption.TopDirectoryOnly;
|
|
var files = Directory.GetFiles(path, "*", searchOption);
|
|
var count = 0;
|
|
|
|
foreach (var file in files)
|
|
{
|
|
var directory = Path.GetDirectoryName(file);
|
|
if (directory is null)
|
|
{
|
|
continue;
|
|
}
|
|
|
|
if (_options.Ignore.Select(Path.GetFullPath).Any(i => directory.StartsWith(i)))
|
|
{
|
|
continue;
|
|
}
|
|
|
|
if (!regex.IsMatch(file))
|
|
{
|
|
continue;
|
|
}
|
|
|
|
var lines = (await File.ReadAllLinesAsync(file).ConfigureAwait(false)) as IEnumerable<string>;
|
|
|
|
if (!_options.Whitespace)
|
|
{
|
|
lines = lines.Where(line => !string.IsNullOrWhiteSpace(line));
|
|
}
|
|
|
|
if (!string.IsNullOrWhiteSpace(_options.IgnoreChars))
|
|
{
|
|
lines = lines.Where(line => line.Trim().Length > 0 && _options.IgnoreChars.IndexOf(line.Trim()[0]) != 0);
|
|
}
|
|
|
|
var fileCount = lines.Count();
|
|
count += fileCount;
|
|
}
|
|
|
|
return count;
|
|
}
|
|
|
|
[Benchmark]
|
|
public int Count()
|
|
{
|
|
var regex = new Regex(_options.Pattern, RegexOptions.Compiled);
|
|
string path = Path.GetFullPath(_options.Path);
|
|
var searchOption = _options.Recurse ? SearchOption.AllDirectories : SearchOption.TopDirectoryOnly;
|
|
string[] files = Directory.GetFiles(path, "*", searchOption);
|
|
var count = 0;
|
|
var ignoreChars = _options.IgnoreChars.AsSpan();
|
|
|
|
foreach (string file in files)
|
|
{
|
|
count = CountLinesInFile(file, _options, regex, ignoreChars, count);
|
|
}
|
|
|
|
return count;
|
|
}
|
|
|
|
private static int CountLinesInFile(string file, Options options, Regex regex, ReadOnlySpan<char> ignoreChars, int count)
|
|
{
|
|
string? directory = Path.GetDirectoryName(file);
|
|
|
|
if (directory is null)
|
|
{
|
|
return count;
|
|
}
|
|
|
|
string directoryFullPath = Path.GetFullPath(directory);
|
|
var ignore = false;
|
|
foreach (string i in options.Ignore)
|
|
{
|
|
if (directoryFullPath.StartsWith(Path.GetFullPath(i)))
|
|
{
|
|
ignore = true;
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (ignore)
|
|
{
|
|
return count;
|
|
}
|
|
|
|
if (!regex.IsMatch(file))
|
|
{
|
|
return count;
|
|
}
|
|
|
|
var fileCount = 0;
|
|
using (var reader = new StreamReader(file))
|
|
{
|
|
while (reader.ReadLine() is { } line)
|
|
{
|
|
var lineSpan = line.AsSpan().Trim();
|
|
if (lineSpan.Length == 0)
|
|
{
|
|
continue;
|
|
}
|
|
|
|
if (options.IgnoreChars.Length > 0 && ignoreChars.IndexOf(lineSpan[0]) != -1)
|
|
{
|
|
continue;
|
|
}
|
|
|
|
fileCount++;
|
|
}
|
|
}
|
|
|
|
count += fileCount;
|
|
return count;
|
|
}
|
|
}
|