Skip to content

Conversation

@Hirogen
Copy link
Collaborator

@Hirogen Hirogen commented Dec 2, 2025

This pull request introduces several major improvements and refactorings to the log reading and columnizer infrastructure, with a focus on performance, extensibility, and benchmarking. The most significant changes include the addition of span-based interfaces and types for log lines, new benchmarking infrastructure using BenchmarkDotNet, and updates to configuration and preferences for reader selection. Deprecated interfaces and settings are also marked for future removal.

Performance and Span-based Infrastructure

  • Introduced new span-based interfaces and types: ILogLineSpan, LogLineSpan, and ILogLineSpanColumnizer, enabling efficient, allocation-free parsing and timestamp extraction of log lines. These changes allow columnizers and readers to operate directly on memory spans, improving performance for large log files. (src/ColumnizerLib/ILogLineSpan.cs, src/ColumnizerLib/ILogLineSpanColumnizer.cs) [1] [2]
  • Added ILogStreamReaderSpan interface for span-based log stream reading, supporting memory-efficient line reading and management. (src/LogExpert.Core/Interface/ILogStreamReaderSpan.cs)

Benchmarking and Testing

  • Added a new LogExpert.Benchmarks project using BenchmarkDotNet, with benchmarks for different stream reader implementations (Legacy, System, Pipeline). This includes project configuration files and a comprehensive benchmark suite for measuring performance across different file sizes and encodings. (src/LogExpert.Benchmarks/LogExpert.Benchmarks.csproj, src/LogExpert.Benchmarks/StreamReaderBenchmarks.cs, src/LogExpert.Benchmarks/Directory.Build.props, src/LogExpert.Benchmarks/Directory.Build.targets, src/Directory.Packages.props) [1] [2] [3] [4] [5]

Configuration and Preferences

  • Added a new ReaderType enum to select between pipeline, legacy, and system reader implementations, and updated the Preferences class to use this new setting. The obsolete UseLegacyReader setting is now marked for removal and ignored in serialization. (src/LogExpert.Core/Config/Preferences.cs, src/LogExpert.Core/Enums/ReaderType.cs) [1] [2]

Codebase Modernization and Cleanup

  • Deprecated the ITextValue interface, added [Obsolete] attributes and extension methods to guide migration to direct property access, and removed unnecessary using statements from several interface files for cleaner code. (src/ColumnizerLib/ITextValue.cs, src/ColumnizerLib/IColumnizedLogLine.cs, src/ColumnizerLib/IColumnizerPriority.cs, src/ColumnizerLib/IFileSystemCallback.cs, src/ColumnizerLib/IInitColumnizer.cs) (F8191294R1, [1] [2] [3] [4] [5]

Log Buffer and Progress Reporting Enhancements

  • Improved LogBuffer with modern C# syntax and clarified constructor usage, and introduced BatchedProgressReporter to efficiently batch progress updates and reduce UI thread overhead during file loading. (src/LogExpert.Core/Classes/Log/LogBuffer.cs, src/LogExpert.Core/Classes/Log/BatchedProgressReporter.cs) [1] [2] [3] [4]

These changes collectively improve performance, maintainability, and extensibility of the log reading and columnizing system, while laying the groundwork for future enhancements.

Benchmark Results

Intel Core Ultra 5 135U Results

Method Mean Error StdDev Ratio RatioSD Rank Gen0 Gen1 Allocated Alloc Ratio
Legacy_ReadAll_Small 1,244.9 us 36.66 us 108.10 us 1.01 0.13 3 21.4844 1.9531 141.16 KB 1.00
System_ReadAll_Small 137.3 us 2.72 us 5.92 us 0.11 0.01 1 19.7754 0.4883 121.83 KB 0.86
Pipeline_ReadAll_Small 1,124.1 us 26.23 us 76.92 us 0.91 0.11 2 31.2500 - 208.16 KB 1.47
Legacy_ReadAll_Medium 24,489.9 us 465.45 us 477.98 us 19.83 1.90 7 343.7500 31.2500 2146.94 KB 15.21
System_ReadAll_Medium 1,928.7 us 38.37 us 91.94 us 1.56 0.16 4 343.7500 7.8125 2127.7 KB 15.07
Pipeline_ReadAll_Medium 12,462.8 us 247.55 us 665.04 us 10.09 1.09 6 515.6250 - 3217.39 KB 22.79
Legacy_ReadAll_Large 466,935.9 us 11,869.21 us 34,996.62 us 378.14 45.49 10 6000.0000 - 40762.68 KB 288.78
System_ReadAll_Large 29,193.8 us 597.24 us 1,760.98 us 23.64 2.64 8 6625.0000 - 40743.64 KB 288.64
Pipeline_ReadAll_Large 148,662.4 us 4,062.03 us 11,913.23 us 120.39 14.88 9 8000.0000 - 51922.25 KB 367.84
Pipeline_ReadAll_Unicode 5,766.2 us 183.72 us 535.93 us 4.67 0.62 5 140.6250 - 870.62 KB 6.17
Pipeline_Seek_And_Read 12,137.3 us 267.44 us 780.14 us 9.83 1.12 6 500.0000 - 3222.25 KB 22.83

AMD Ryzen 9 5900X Results

Method Mean Error StdDev Median Ratio RatioSD Rank Gen0 Gen1 Allocated Alloc Ratio
Legacy_ReadAll_Small 408.83 us 3.589 us 2.997 us 408.15 us 1.00 0.01 3 8.3008 0.4883 141.16 KB 1.00
System_ReadAll_Small 34.74 us 0.394 us 0.368 us 34.75 us 0.08 0.00 1 7.4463 0.1831 121.83 KB 0.86
Pipeline_ReadAll_Small 321.33 us 6.419 us 16.684 us 326.78 us 0.79 0.04 2 14.1602 - 231.37 KB 1.64
Legacy_ReadAll_Medium 8,118.16 us 27.524 us 25.746 us 8,114.55 us 19.86 0.15 7 125.0000 - 2146.94 KB 15.21
System_ReadAll_Medium 469.01 us 3.139 us 2.937 us 468.14 us 1.15 0.01 4 129.8828 3.4180 2127.7 KB 15.07
Pipeline_ReadAll_Medium 3,726.37 us 74.304 us 213.191 us 3,777.91 us 9.12 0.52 6 218.7500 - 3618.28 KB 25.63
Legacy_ReadAll_Large 166,390.37 us 3,288.058 us 3,075.651 us 165,532.20 us 407.01 7.82 9 2250.0000 - 40762.68 KB 288.78
System_ReadAll_Large 7,711.01 us 153.778 us 277.294 us 7,690.47 us 18.86 0.68 7 2484.3750 15.6250 40743.64 KB 288.64
Pipeline_ReadAll_Large 43,030.24 us 858.679 us 1,146.312 us 43,039.15 us 105.26 2.85 8 3615.3846 - 59321.54 KB 420.25
Pipeline_ReadAll_Unicode 1,558.77 us 31.041 us 61.271 us 1,576.08 us 3.81 0.15 5 66.4063 - 1146.29 KB 8.12
Pipeline_Seek_And_Read 3,623.49 us 80.398 us 237.055 us 3,540.02 us 8.86 0.58 6 207.0313 3.9063 3399.82 KB 24.09

Copilot finished reviewing on behalf of Hirogen December 2, 2025 21:35
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This pull request introduces a significant modernization effort focused on performance optimization through span-based APIs and new reader implementations, while laying the groundwork for future improvements. The PR adds extensive documentation, new interfaces for zero-allocation log processing, and two new stream reader implementations (Channel-based and Pipeline-based), though the Pipeline implementation is incomplete. The changes also include API refinements, code modernization, and comprehensive test coverage for new IPC functionality.

Key Changes:

  • New span-based interfaces (ILogLineSpan, ILogLineSpanColumnizer, ILogStreamReaderSpan) to enable allocation-free log line processing
  • Reader architecture refactoring with new ReaderType enum and factory pattern for selecting between Legacy, System, Channel, and Pipeline readers (though the enum definition and Pipeline implementation are incomplete)
  • Comprehensive documentation in PIPELINES_IMPLEMENTATION_STRATEGY.md detailing the implementation approach for a high-performance Pipeline-based reader

Reviewed changes

Copilot reviewed 18 out of 20 changed files in this pull request and generated 26 comments.

Show a summary per file
File Description
src/docs/performance/PIPELINES_IMPLEMENTATION_STRATEGY.md Adds comprehensive 385-line implementation strategy document for Pipeline-based stream reader with architecture details, performance expectations, and integration guidance
src/LogExpert.UI/Dialogs/SettingsDialog.Designer.cs Reduces minimum line length from 20,000 to 1,000 characters, providing more flexibility but potentially allowing problematic configurations
src/LogExpert.UI/Controls/LogWindow/LogWindow.cs Modernizes regex usage by converting to source-generated regexes using [GeneratedRegex] attribute for improved performance
src/LogExpert.Tests/IPC/ActiveWindowTrackingTests.cs Adds comprehensive 312-line test suite for active window tracking functionality with scenario, edge case, and integration tests
src/LogExpert.Tests/ColumnizerPickerTest.cs Minor formatting cleanup adding blank lines for improved readability in test LogLine implementation
src/LogExpert.Core/Interface/ILogStreamReaderSpan.cs Introduces new interface for span-based stream reading with memory management methods (marked internal, lacks documentation)
src/LogExpert.Core/Interface/ILogStreamReader.cs Code formatting cleanup removing BOM and normalizing whitespace
src/LogExpert.Core/Classes/Log/PositionAwareStreamReaderPipeline.cs Adds skeleton implementation of Pipeline-based reader with most methods throwing NotImplementedException - incomplete and non-functional
src/LogExpert.Core/Classes/Log/PositionAwareStreamReaderChannel.cs Implements new Channel-based asynchronous log reader with pooled buffers and backpressure handling, now the default reader type
src/LogExpert.Core/Classes/Log/LogfileReader.cs Refactors reader selection to use ReaderType enum with switch expression, removes LogLine record, hardcodes Channel reader as default
src/LogExpert.Core/Classes/Log/LogBuffer.cs Modernizes code with collection expressions, improved formatting, and refactored conditional logic
src/ColumnizerLib/ITextValue.cs Marks interface as obsolete and adds extension methods for backward compatibility
src/ColumnizerLib/ILogLineSpanColumnizer.cs Introduces new interface for span-based columnizer operations to reduce string allocations
src/ColumnizerLib/ILogLineSpan.cs Defines ILogLineSpan interface and LogLineSpan ref struct (has compilation errors - ref struct cannot implement interface)
src/ColumnizerLib/ILogLine.cs Adds LogLine readonly struct implementation to replace previous record-based approach
src/ColumnizerLib/IInitColumnizer.cs Removes unused using statements and fixes trailing whitespace in documentation comments
src/ColumnizerLib/IFileSystemCallback.cs Removes unused using statements and normalizes method formatting
src/ColumnizerLib/IColumnizerPriority.cs Removes unused using statements and normalizes method formatting
src/ColumnizerLib/IColumnizerConfigurator.cs Fixes trailing whitespace in documentation comments and normalizes method formatting
src/ColumnizerLib/IColumnizedLogLine.cs Removes unused using statements and extra blank line
Files not reviewed (1)
  • src/LogExpert.UI/Dialogs/SettingsDialog.Designer.cs: Language not supported

_updateIntervalMs = updateIntervalMs;

// Start timer
_timer = new Timer(ProcessQueue, null, updateIntervalMs, updateIntervalMs);
Comment on lines +82 to +86
catch (Exception ex)
{
// Log but don't crash
System.Diagnostics.Debug.WriteLine($"Error in progress callback: {ex.Message}");
}
private LineSegment? _currentSegment;

private PipeReader _pipeReader;
private CancellationTokenSource _cts;
Comment on lines +265 to +268
catch (Exception)
{
// Ignore errors during completion
}
Comment on lines +324 to +328
catch (Exception ex)
{
// Store exception to rethrow in ReadLine
Volatile.Write(ref _producerException, ex);
}
private LineSegment? _currentSegment;

private PipeReader _pipeReader;
private CancellationTokenSource _cts;
Comment on lines +290 to +293
catch (Exception)
{
// Ignore errors during completion
}
Comment on lines +349 to +353
catch (Exception ex)
{
// Store exception to rethrow in ReadLine
Volatile.Write(ref _producerException, ex);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants