Skip to content

Enhance in-memory reading, benchmarks, and documentation updates - #49

Merged
GabrielMarquezMatte merged 10 commits into
masterfrom
develop
Jul 29, 2026
Merged

Enhance in-memory reading, benchmarks, and documentation updates#49
GabrielMarquezMatte merged 10 commits into
masterfrom
develop

Conversation

@GabrielMarquezMatte

Copy link
Copy Markdown
Owner

This pull request introduces significant improvements to project documentation, builds, and workflows, focusing on better contributor guidance, CI reliability, and release transparency. Notably, it adds comprehensive documentation for architecture, contributing, and code of conduct, enhances GitHub issue and pull request templates, and improves CI and release workflows with formatting checks and SBOM generation.

Documentation and Contributor Guidance:

  • Added ARCHITECTURE.md describing the codebase structure, design decisions, and conventions, to help new contributors understand the project quickly.
  • Added CONTRIBUTING.md outlining build/test expectations, API review, test requirements, and how to report bugs/features or security issues.
  • Added CODE_OF_CONDUCT.md to set community standards and reporting procedures for unacceptable behavior.
  • Added GitHub issue templates for bugs and feature requests to standardize and streamline reporting. [1] [2]
  • Added a pull request template to clarify requirements and ensure consistent PR quality.

CI and Workflow Improvements:

  • CI now verifies code formatting (whitespace) on Ubuntu builds, ensuring consistent code style across contributions. (.github/workflows/ci.yml)
  • The CodeQL workflow now runs for both master and develop branches, increasing security coverage. (.github/workflows/codeql.yml)

Release Process Enhancements:

  • The release workflow now generates an SPDX SBOM (Software Bill of Materials) for published artifacts, improving supply chain transparency. (.github/workflows/release.yml)

README and Benchmark Clarifications:

  • Expanded the README with more detailed benchmark methodology, clarifying how results should be interpreted for fair comparisons and updating in-memory path benchmark results and explanations. [1] [2]

These changes collectively make the project more maintainable, secure, and welcoming for contributors, while improving CI reliability and release artifact transparency.

Gabriel Matte added 9 commits July 28, 2026 18:37
- Consolidated real-world XLSX tests into RealWorldXlsxCorpusTests, focusing on genuine producer-exported binaries.
- Introduced XlsxDialectShapeTests and XlsxProducerDialectShapeTests for testing known quirks of specific producers with hand-authored XML/ZIP fragments.
- Updated WorkbookWriterTests to simplify decimal parsing logic.
- Added utility methods in XlsWorkbookBuilder for handling binary data and offsets.
- Improved ZipMemoryIndexTests documentation for clarity on in-memory ZIP central-directory reading.
- Added a sample XLSX file (sheetjs-sample.xlsx) for testing purposes.
- Introduced a bug report template to streamline issue reporting, including sections for reproduction steps, expected vs actual behavior, and environment details.
- Added a feature request template to facilitate suggestions for new features, outlining problem statements, proposed APIs, and alternatives considered.

chore: Create pull request template

- Established a pull request template to ensure consistency in submissions, including a checklist for build verification, public API changes, and test coverage.

ci: Enhance CI workflows

- Added a formatting verification step to the CI pipeline for Ubuntu.
- Integrated SBOM generation into the release workflow for better dependency tracking.

docs: Add architecture documentation

- Created an architecture document detailing the codebase structure, format families, shared components, and design decisions.

docs: Implement Code of Conduct and Contribution guidelines

- Added a Code of Conduct to promote a respectful community environment.
- Established contributing guidelines to clarify expectations for contributions, including build requirements and testing protocols.

fix: Handle large OLE root entry sizes

- Implemented a check to throw an exception if the OLE root entry size exceeds the container's limits, preventing silent failures.

test: Add tests for new features and edge cases

- Developed tests for XLSX and CSV cancellation during large sheet processing.
- Added tests to ensure proper handling of overlong numeric XML entities and forged root entry sizes.
@github-actions

github-actions Bot commented Jul 29, 2026

Copy link
Copy Markdown

Benchmark Results

Measured on ubuntu-latest (GitHub Actions). Runner noise may affect absolute numbers; use these for relative comparisons within a PR.

ExcelReader.Benchmarks.ColdStartBenchmark


BenchmarkDotNet v0.15.8, Linux Ubuntu 24.04.4 LTS (Noble Numbat)
Intel Xeon 6973P-C 2.60GHz, 1 CPU, 4 logical and 2 physical cores
.NET SDK 10.0.302
  [Host]     : .NET 10.0.10 (10.0.10, 10.0.1026.32716), X64 RyuJIT x86-64-v4
  Job-GOEFXF : .NET 10.0.10 (10.0.10, 10.0.1026.32716), X64 RyuJIT x86-64-v4

InvocationCount=1  IterationCount=1  LaunchCount=16  
RunStrategy=ColdStart  UnrollFactor=1  WarmupCount=0  

Method Rows Mean Error StdDev Allocated
TypedParseFirstUse 200 33.20 ms 2.510 ms 2.466 ms 29.57 KB
RecordWriteFirstUse 200 18.69 ms 0.631 ms 0.620 ms 79.41 KB

ExcelReader.Benchmarks.CsvParseBenchmark


BenchmarkDotNet v0.15.8, Linux Ubuntu 24.04.4 LTS (Noble Numbat)
AMD EPYC 7763 3.17GHz, 1 CPU, 4 logical and 2 physical cores
.NET SDK 10.0.302
  [Host]     : .NET 10.0.10 (10.0.10, 10.0.1026.32716), X64 RyuJIT x86-64-v3
  Job-MEHJPP : .NET 10.0.10 (10.0.10, 10.0.1026.32716), X64 RyuJIT x86-64-v3

IterationCount=5  WarmupCount=1  

Method Rows Mean Error StdDev Ratio RatioSD Gen0 Gen1 Allocated Alloc Ratio
ExcelParserSync 50000 8.611 ms 0.5451 ms 0.1416 ms 1.00 0.02 234.3750 - 3.86 MB 1.00
ExcelParserAsync 50000 8.373 ms 0.0722 ms 0.0112 ms 0.97 0.01 234.3750 - 3.86 MB 1.00
Sep 50000 14.695 ms 0.3010 ms 0.0466 ms 1.71 0.03 234.3750 - 3.87 MB 1.00
Sylvan 50000 19.949 ms 0.6532 ms 0.1696 ms 2.32 0.04 656.2500 62.5000 10.95 MB 2.84
CsvHelperLib 50000 35.547 ms 0.2134 ms 0.0554 ms 4.13 0.06 857.1429 71.4286 14.41 MB 3.73

ExcelReader.Benchmarks.CsvReadBenchmark


BenchmarkDotNet v0.15.8, Linux Ubuntu 24.04.4 LTS (Noble Numbat)
AMD EPYC 7763 2.63GHz, 1 CPU, 4 logical and 2 physical cores
.NET SDK 10.0.302
  [Host]     : .NET 10.0.10 (10.0.10, 10.0.1026.32716), X64 RyuJIT x86-64-v3
  Job-MEHJPP : .NET 10.0.10 (10.0.10, 10.0.1026.32716), X64 RyuJIT x86-64-v3

IterationCount=5  WarmupCount=1  

Method Rows Mean Error StdDev Ratio Gen0 Gen1 Allocated Alloc Ratio
ExcelReader 50000 6.360 ms 0.0354 ms 0.0055 ms 1.00 - - 232 B 1.00
ExcelReaderAsync 50000 5.672 ms 0.0205 ms 0.0032 ms 0.89 - - 368 B 1.59
Sep 50000 13.554 ms 0.3709 ms 0.0963 ms 2.13 - - 4024 B 17.34
Sylvan 50000 6.761 ms 0.0376 ms 0.0058 ms 1.06 93.7500 7.8125 1688701 B 7,278.88
CsvHelperLib 50000 36.588 ms 0.2691 ms 0.0699 ms 5.75 857.1429 71.4286 15073424 B 64,971.66

ExcelReader.Benchmarks.CsvWriteBenchmark


BenchmarkDotNet v0.15.8, Linux Ubuntu 24.04.4 LTS (Noble Numbat)
AMD EPYC 7763 2.45GHz, 1 CPU, 4 logical and 2 physical cores
.NET SDK 10.0.302
  [Host]     : .NET 10.0.10 (10.0.10, 10.0.1026.32716), X64 RyuJIT x86-64-v3
  Job-MEHJPP : .NET 10.0.10 (10.0.10, 10.0.1026.32716), X64 RyuJIT x86-64-v3

IterationCount=5  WarmupCount=1  

Method Rows Mean Error StdDev Ratio RatioSD Gen0 Gen1 Gen2 Allocated Alloc Ratio
ExcelReaderWriter 50000 9.712 ms 0.3714 ms 0.0965 ms 1.00 0.01 500.0000 500.0000 500.0000 4 MB 1.00
Sep 50000 10.482 ms 0.5095 ms 0.1323 ms 1.08 0.02 500.0000 500.0000 500.0000 4.01 MB 1.00
SylvanWriter 50000 11.077 ms 0.3106 ms 0.0806 ms 1.14 0.01 500.0000 500.0000 500.0000 4.04 MB 1.01
CsvHelperLib 50000 21.191 ms 0.4657 ms 0.1209 ms 2.18 0.02 1187.5000 656.2500 593.7500 13.79 MB 3.44

ExcelReader.Benchmarks.ParseBenchmark


BenchmarkDotNet v0.15.8, Linux Ubuntu 24.04.4 LTS (Noble Numbat)
AMD EPYC 7763 3.17GHz, 1 CPU, 4 logical and 2 physical cores
.NET SDK 10.0.302
  [Host]     : .NET 10.0.10 (10.0.10, 10.0.1026.32716), X64 RyuJIT x86-64-v3
  Job-MEHJPP : .NET 10.0.10 (10.0.10, 10.0.1026.32716), X64 RyuJIT x86-64-v3

IterationCount=5  WarmupCount=1  

Method Rows Mean Error StdDev Ratio RatioSD Gen0 Allocated Alloc Ratio
ExcelParserSync 50000 21.340 ms 0.3770 ms 0.0583 ms 1.00 0.00 218.7500 3968.2 KB 1.000
ExcelParserStructSync 50000 20.771 ms 0.2097 ms 0.0545 ms 0.97 0.00 93.7500 1624.48 KB 0.409
RefParserParseNamedSync 50000 19.875 ms 0.1654 ms 0.0430 ms 0.93 0.00 - 13.08 KB 0.003
ExcelParserAsync 50000 21.787 ms 0.1111 ms 0.0172 ms 1.02 0.00 218.7500 3970.35 KB 1.001
ExcelParserXlsbSync 50000 9.821 ms 0.0626 ms 0.0097 ms 0.46 0.00 234.3750 3969.84 KB 1.000
ExcelParserXlsbAsync 50000 10.938 ms 0.0778 ms 0.0120 ms 0.51 0.00 234.3750 3972.41 KB 1.001
MiniExcel 50000 228.869 ms 8.9743 ms 1.3888 ms 10.72 0.06 12000.0000 202527.9 KB 51.038
Sylvan 50000 88.786 ms 1.2731 ms 0.1970 ms 4.16 0.01 500.0000 10726.37 KB 2.703
SylvanAsync 50000 89.709 ms 2.6041 ms 0.4030 ms 4.20 0.02 - 10727.74 KB 2.703

ExcelReader.Benchmarks.ReadBenchmark


BenchmarkDotNet v0.15.8, Linux Ubuntu 24.04.4 LTS (Noble Numbat)
AMD EPYC 7763 2.63GHz, 1 CPU, 4 logical and 2 physical cores
.NET SDK 10.0.302
  [Host]     : .NET 10.0.10 (10.0.10, 10.0.1026.32716), X64 RyuJIT x86-64-v3
  Job-MEHJPP : .NET 10.0.10 (10.0.10, 10.0.1026.32716), X64 RyuJIT x86-64-v3

IterationCount=5  WarmupCount=1  

Method Rows Mean Error StdDev Ratio RatioSD Gen0 Allocated Alloc Ratio
ExcelReader 50000 16.256 ms 0.0799 ms 0.0207 ms 1.00 0.00 - 12.59 KB 1.00
ExcelReaderAsync 50000 17.905 ms 0.1391 ms 0.0361 ms 1.10 0.00 - 14.73 KB 1.17
ExcelReaderXlsb 50000 6.619 ms 0.0593 ms 0.0154 ms 0.41 0.00 - 14.23 KB 1.13
ExcelReaderXlsbAsync 50000 7.023 ms 0.0360 ms 0.0056 ms 0.43 0.00 - 16.79 KB 1.33
ExcelReaderMaterialized 50000 18.497 ms 0.0927 ms 0.0241 ms 1.14 0.00 93.7500 1623.92 KB 128.95
MiniExcel 50000 216.477 ms 2.1907 ms 0.3390 ms 13.32 0.02 13000.0000 214016.6 KB 16,993.87
Sylvan 50000 57.114 ms 2.2760 ms 0.5911 ms 3.51 0.03 - 1939.18 KB 153.98

ExcelReader.Benchmarks.RealDataReadBenchmark


BenchmarkDotNet v0.15.8, Linux Ubuntu 24.04.4 LTS (Noble Numbat)
AMD EPYC 7763 2.45GHz, 1 CPU, 4 logical and 2 physical cores
.NET SDK 10.0.302
  [Host]     : .NET 10.0.10 (10.0.10, 10.0.1026.32716), X64 RyuJIT x86-64-v3
  Job-MEHJPP : .NET 10.0.10 (10.0.10, 10.0.1026.32716), X64 RyuJIT x86-64-v3

IterationCount=5  WarmupCount=1  

Method Mean Error StdDev Ratio RatioSD Gen0 Gen1 Allocated Alloc Ratio
Xlsx_ExcelReader 91.007 ms 1.4967 ms 0.2316 ms 1.00 0.00 - - 35360 B 1.000
Xlsx_Sylvan 330.719 ms 12.6633 ms 1.9597 ms 3.63 0.02 - - 659568 B 18.653
Xlsx_ExcelReader_Materialized 95.377 ms 1.0469 ms 0.1620 ms 1.05 0.00 - - 67288 B 1.903
Xlsx_ExcelReader_Prefetch 99.971 ms 14.8206 ms 3.8489 ms 1.10 0.04 - - 140911 B 3.985
Xlsx_ExcelReader_Memory 92.788 ms 0.5680 ms 0.0879 ms 1.02 0.00 - - 5104 B 0.144
Xlsx_ExcelReader_Memory_Prefetch 99.810 ms 22.2112 ms 5.7682 ms 1.10 0.06 - - 97832 B 2.767
Xlsm_ExcelReader 92.888 ms 6.4469 ms 1.6742 ms 1.02 0.02 - - 35400 B 1.001
Xlsm_Sylvan 305.651 ms 3.3822 ms 0.8783 ms 3.36 0.01 - - 659648 B 18.655
Xlsm_ExcelReader_Materialized 96.216 ms 2.7680 ms 0.7188 ms 1.06 0.01 - - 67328 B 1.904
Xlsm_ExcelReader_Prefetch 95.848 ms 15.4271 ms 4.0064 ms 1.05 0.04 - - 129800 B 3.671
Xlsm_ExcelReader_Memory 91.948 ms 1.4588 ms 0.2257 ms 1.01 0.00 - - 5104 B 0.144
Xlsm_ExcelReader_Memory_Prefetch 100.159 ms 20.5693 ms 5.3418 ms 1.10 0.05 - - 98016 B 2.772
Xlsb_ExcelReader 35.094 ms 0.2758 ms 0.0427 ms 0.39 0.00 - - 26056 B 0.737
Xlsb_Sylvan 45.930 ms 0.2676 ms 0.0695 ms 0.50 0.00 - - 346675 B 9.804
Xlsb_ExcelReader_Materialized 38.220 ms 0.1228 ms 0.0319 ms 0.42 0.00 - - 57984 B 1.640
Xlsb_ExcelReader_Prefetch 20.859 ms 4.2615 ms 1.1067 ms 0.23 0.01 - - 43914 B 1.242
Xlsb_ExcelReader_Memory 36.092 ms 0.1990 ms 0.0308 ms 0.40 0.00 - - 14792 B 0.418
Xlsb_ExcelReader_Memory_Prefetch 19.540 ms 2.3399 ms 0.6077 ms 0.21 0.01 - - 21553 B 0.610
Xls_ExcelReader 20.746 ms 0.0901 ms 0.0139 ms 0.23 0.00 - - 10288 B 0.291
Xls_Sylvan 26.915 ms 0.1437 ms 0.0373 ms 0.30 0.00 - - 190366 B 5.384
Xls_ExcelReader_Materialized 24.721 ms 0.3694 ms 0.0572 ms 0.27 0.00 - - 42216 B 1.194
Xls_ExcelReader_Memory 15.555 ms 0.0529 ms 0.0082 ms 0.17 0.00 - - 10288 B 0.291
Csv_ExcelReader 9.322 ms 0.0344 ms 0.0089 ms 0.10 0.00 - - 232 B 0.007
Csv_Sylvan 16.874 ms 0.6686 ms 0.1736 ms 0.19 0.00 2218.7500 125.0000 37484040 B 1,060.069
Csv_ExcelReader_Materialized 30.716 ms 0.4549 ms 0.1181 ms 0.34 0.00 2218.7500 - 37442840 B 1,058.904
Csv_ExcelReader_Memory 9.154 ms 0.0257 ms 0.0040 ms 0.10 0.00 - - 168 B 0.005

ExcelReader.Benchmarks.RecordWriteBenchmark


BenchmarkDotNet v0.15.8, Linux Ubuntu 24.04.4 LTS (Noble Numbat)
AMD EPYC 7763 2.45GHz, 1 CPU, 4 logical and 2 physical cores
.NET SDK 10.0.302
  [Host]     : .NET 10.0.10 (10.0.10, 10.0.1026.32716), X64 RyuJIT x86-64-v3
  Job-MEHJPP : .NET 10.0.10 (10.0.10, 10.0.1026.32716), X64 RyuJIT x86-64-v3

IterationCount=5  WarmupCount=1  

Method Rows Mean Error StdDev Ratio Gen0 Gen1 Gen2 Allocated Alloc Ratio
Xlsx 50000 21.227 ms 0.1542 ms 0.0239 ms 1.00 500.0000 500.0000 500.0000 4.02 MB 1.00
Xlsb 50000 10.440 ms 0.1388 ms 0.0215 ms 0.49 500.0000 500.0000 500.0000 4.02 MB 1.00
Xls 50000 7.724 ms 0.2210 ms 0.0574 ms 0.36 273.4375 273.4375 273.4375 4.03 MB 1.00
Csv 50000 10.572 ms 0.3806 ms 0.0988 ms 0.50 500.0000 500.0000 500.0000 4 MB 1.00

ExcelReader.Benchmarks.WriteBenchmark


BenchmarkDotNet v0.15.8, Linux Ubuntu 24.04.4 LTS (Noble Numbat)
AMD EPYC 7763 2.45GHz, 1 CPU, 4 logical and 2 physical cores
.NET SDK 10.0.302
  [Host]     : .NET 10.0.10 (10.0.10, 10.0.1026.32716), X64 RyuJIT x86-64-v3
  Job-MEHJPP : .NET 10.0.10 (10.0.10, 10.0.1026.32716), X64 RyuJIT x86-64-v3

IterationCount=5  WarmupCount=1  

Method Rows Mean Error StdDev Ratio RatioSD Gen0 Gen1 Gen2 Allocated Alloc Ratio
ExcelReaderWriter 50000 20.402 ms 0.5921 ms 0.1538 ms 1.00 0.01 500.0000 500.0000 500.0000 4.02 MB 1.00
ExcelReaderWriterSharedStrings 50000 20.951 ms 0.2353 ms 0.0611 ms 1.03 0.01 500.0000 500.0000 500.0000 4.06 MB 1.01
ExcelReaderXlsbWriter 50000 10.214 ms 0.1837 ms 0.0477 ms 0.50 0.00 500.0000 500.0000 500.0000 4.02 MB 1.00
ExcelReaderXlsbWriterSharedStrings 50000 9.869 ms 0.2079 ms 0.0540 ms 0.48 0.00 500.0000 500.0000 500.0000 4.06 MB 1.01
MiniExcel 50000 105.948 ms 5.6075 ms 0.8678 ms 5.19 0.05 5000.0000 1000.0000 1000.0000 84.89 MB 21.13
SpreadCheetah 50000 21.973 ms 0.3501 ms 0.0542 ms 1.08 0.01 1437.5000 718.7500 718.7500 15.84 MB 3.94

ExcelReader.Benchmarks.XlsReadBenchmark


BenchmarkDotNet v0.15.8, Linux Ubuntu 24.04.4 LTS (Noble Numbat)
AMD EPYC 7763 2.63GHz, 1 CPU, 4 logical and 2 physical cores
.NET SDK 10.0.302
  [Host]     : .NET 10.0.10 (10.0.10, 10.0.1026.32716), X64 RyuJIT x86-64-v3
  Job-MEHJPP : .NET 10.0.10 (10.0.10, 10.0.1026.32716), X64 RyuJIT x86-64-v3

IterationCount=5  WarmupCount=1  

Method Rows Mean Error StdDev Ratio Gen0 Gen1 Allocated Alloc Ratio
ExcelReader 50000 6.428 ms 0.0137 ms 0.0021 ms 1.00 - - 2.97 KB 1.00
ExcelReaderAsync 50000 6.336 ms 0.0207 ms 0.0054 ms 0.99 - - 3.04 KB 1.02
Sylvan 50000 8.659 ms 0.0627 ms 0.0163 ms 1.35 93.7500 15.6250 1717.73 KB 578.60

ExcelReader.Benchmarks.XlsWriteBenchmark


BenchmarkDotNet v0.15.8, Linux Ubuntu 24.04.4 LTS (Noble Numbat)
AMD EPYC 7763 2.45GHz, 1 CPU, 4 logical and 2 physical cores
.NET SDK 10.0.302
  [Host]     : .NET 10.0.10 (10.0.10, 10.0.1026.32716), X64 RyuJIT x86-64-v3
  Job-MEHJPP : .NET 10.0.10 (10.0.10, 10.0.1026.32716), X64 RyuJIT x86-64-v3

IterationCount=5  WarmupCount=1  

Method Rows Mean Error StdDev Ratio Gen0 Gen1 Gen2 Allocated Alloc Ratio
XlsWriter 50000 7.777 ms 0.0774 ms 0.0201 ms 1.00 492.1875 492.1875 492.1875 16.03 MB 1.00
XlsxWriter 50000 20.718 ms 0.1317 ms 0.0342 ms 2.66 500.0000 500.0000 500.0000 4.02 MB 0.25

@codecov-commenter

Copy link
Copy Markdown

⚠️ Please install the 'codecov app svg image' to ensure uploads and comments are reliably processed by Codecov.

Codecov Report

❌ Patch coverage is 82.71605% with 14 lines in your changes missing coverage. Please review.
✅ Project coverage is 89.07%. Comparing base (33f8996) to head (1cd3603).

Files with missing lines Patch % Lines
src/ExcelReader.Core/Reader/CsvReader.cs 69.23% 6 Missing and 2 partials ⚠️
src/ExcelReader.Core/Reader/BiffCursor.cs 76.19% 2 Missing and 3 partials ⚠️
src/ExcelReader.Core/Reader/XlsxXml.cs 50.00% 0 Missing and 1 partial ⚠️
❗ Your organization needs to install the Codecov GitHub app to enable full functionality.
Additional details and impacted files
@@            Coverage Diff             @@
##           master      #49      +/-   ##
==========================================
+ Coverage   88.98%   89.07%   +0.08%     
==========================================
  Files          94       95       +1     
  Lines        6328     6389      +61     
  Branches     1192     1200       +8     
==========================================
+ Hits         5631     5691      +60     
- Misses        460      462       +2     
+ Partials      237      236       -1     

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@GabrielMarquezMatte
GabrielMarquezMatte merged commit 954a86e into master Jul 29, 2026
13 checks passed
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