-
Notifications
You must be signed in to change notification settings - Fork 469
feat: Introduce FastExcel Benchmark Performance Testing Module #575
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
feat: Introduce FastExcel Benchmark Performance Testing Module #575
Conversation
|
CI Benchmark Run Completed Successfully: https://github.com/GOODBOY008/fastexcel/actions/runs/17709908635 To view the benchmark reports:
There are a few issues to address:
|
|
I'm really excited about this PR. However, it's quite large, so the code review will take some time. Also, no offense intended, but I'd like to ask: Did you use AI-generated code in this PR? |
@psxjoy Yes, some parts (like the comparison report, memory profiler logic, and quickstart scripts) were AI-assisted.AI is quite effective in these scenarios, I’ve verified them to make sure they work correctly. I noticed the artifact wasn’t accessible, so I’ve uploaded the results for your review. |
|
Hi, @GOODBOY008 Regarding this PR, I still have some questions:
Please refer to the above suggestions and make appropriate modifications to the PR content. After that, we will vote on this PR together with other reviewers ASAP. |
|
Hi @delei For the first point, I understand the concern about the PR size — my intention was to split the work into stages, so this submission might look a bit large. Regarding the second and third points: I’m fine with keeping only the JMH core classes for now, but I’d like to highlight the above considerations. |
5a95c2d to
1be72cb
Compare
|
@delei PTAL |
1be72cb to
1824158
Compare
1824158 to
a828caf
Compare
✅ Deploy Preview for fesod ready!
To edit notification comments on pull requests, go to your Netlify project configuration. |
a828caf to
3a2c467
Compare
3a2c467 to
4ede42b
Compare
There was a problem hiding this 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 PR introduces a comprehensive JMH-based benchmark module for the FastExcel library, enabling performance testing and comparisons with Apache POI across various operations (read, write, fill) and dataset sizes. The module includes memory profiling capabilities, test data generation utilities, and comparison benchmarks to validate FastExcel's performance claims.
Changes:
- New
fesod-benchmarkmodule with complete JMH integration and Maven configuration - Benchmark suites for read, write, and fill operations across multiple dataset sizes and file formats
- Memory profiling utilities with GC tracking and detailed statistics
- Comparison benchmarks between FastExcel and Apache POI
- Comprehensive test data generation with configurable characteristics
Reviewed changes
Copilot reviewed 14 out of 14 changed files in this pull request and generated 20 comments.
Show a summary per file
| File | Description |
|---|---|
| pom.xml | Added fesod-benchmark module to parent POM |
| fesod-benchmark/pom.xml | New Maven configuration with JMH dependencies and shade plugin |
| fesod-benchmark/benchmark.md | Documentation for running and interpreting benchmarks |
| MemoryProfiler.java | Utility for real-time memory profiling with GC tracking |
| DataGenerator.java | Test data generation with multiple data types and characteristics |
| BenchmarkFileUtil.java | File management utilities for benchmark operations |
| BenchmarkData.java | Data model with 20 fields covering various Excel data types |
| BenchmarkConfiguration.java | Configuration enums for dataset sizes and file formats |
| AbstractBenchmark.java | Base class providing common benchmark functionality |
| WriteBenchmark.java | Write operation benchmarks for different sizes and scenarios |
| ReadBenchmark.java | Read operation benchmarks with multiple listener patterns |
| FillBenchmark.java | Template fill operation benchmarks |
| FastExcelVsPoiBenchmark.java | Comparison benchmarks between FastExcel and Apache POI |
| ComparisonBenchmarkRunner.java | Runner for executing comparison benchmarks |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| // Test files for different sizes and formats | ||
| private String xlsxSmallFile; | ||
| private String xlsxMediumFile; | ||
| private String xlsEXTRA_LARGEFile; |
Copilot
AI
Jan 16, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Variable name xlsEXTRA_LARGEFile uses inconsistent capitalization mixing underscores with camelCase. Should be xlsxLargeFile to match the naming pattern of other variables like xlsxSmallFile and xlsxMediumFile.
| private String xlsEXTRA_LARGEFile; | |
| private String xlsxLargeFile; |
| } | ||
|
|
||
| @Benchmark | ||
| public void readXlsEXTRA_LARGE(Blackhole blackhole) throws Exception { |
Copilot
AI
Jan 16, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Method name readXlsEXTRA_LARGE uses inconsistent capitalization with underscores and uppercase. Should be readXlsxLarge to follow Java naming conventions and match the pattern of other methods like readXlsxSmall and readXlsxMedium.
| public void readXlsEXTRA_LARGE(Blackhole blackhole) throws Exception { | |
| public void readXlsxLarge(Blackhole blackhole) throws Exception { |
|
|
||
| // Stream reading benchmarks | ||
| @Benchmark | ||
| public void readXlsEXTRA_LARGEWithStreaming(Blackhole blackhole) throws Exception { |
Copilot
AI
Jan 16, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Method name readXlsEXTRA_LARGEWithStreaming uses inconsistent capitalization. Should be readXlsxLargeWithStreaming to follow Java naming conventions.
| public void readXlsEXTRA_LARGEWithStreaming(Blackhole blackhole) throws Exception { | |
| public void readXlsxLargeWithStreaming(Blackhole blackhole) throws Exception { |
|
|
||
| // Different listener types benchmarks | ||
| @Benchmark | ||
| public void readXlsEXTRA_LARGECountingOnly(Blackhole blackhole) throws Exception { |
Copilot
AI
Jan 16, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Method name readXlsEXTRA_LARGECountingOnly uses inconsistent capitalization. Should be readXlsxLargeCountingOnly to follow Java naming conventions.
| public void readXlsEXTRA_LARGECountingOnly(Blackhole blackhole) throws Exception { | |
| public void readXlsxLargeCountingOnly(Blackhole blackhole) throws Exception { |
| } | ||
|
|
||
| @Benchmark | ||
| public void readXlsEXTRA_LARGECollecting(Blackhole blackhole) throws Exception { |
Copilot
AI
Jan 16, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Method name readXlsEXTRA_LARGECollecting uses inconsistent capitalization. Should be readXlsxLargeCollecting to follow Java naming conventions.
| public void readXlsEXTRA_LARGECollecting(Blackhole blackhole) throws Exception { | |
| public void readXlsxLargeCollecting(Blackhole blackhole) throws Exception { |
| "Generated {} rows in {} ms ({} rows/sec)", | ||
| rowCount, | ||
| duration, | ||
| duration > 0 ? (rowCount * 1000 / duration) : "N/A"); |
Copilot
AI
Jan 16, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Potential overflow in int multiplication before it is converted to long by use in a numeric context.
| duration > 0 ? (rowCount * 1000 / duration) : "N/A"); | |
| duration > 0 ? (rowCount * 1000L / duration) : "N/A"); |
| protected void setupBenchmark() throws Exception { | ||
| // Custom setup logic if needed | ||
| } | ||
|
|
Copilot
AI
Jan 16, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This method overrides AbstractBenchmark.tearDownBenchmark; it is advisable to add an Override annotation.
| @Override |
|
|
||
| protected void setupBenchmark() throws Exception { | ||
| // Custom setup logic if needed | ||
| } | ||
|
|
Copilot
AI
Jan 16, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This method overrides AbstractBenchmark.setupBenchmark; it is advisable to add an Override annotation.
| protected void setupBenchmark() throws Exception { | |
| // Custom setup logic if needed | |
| } | |
| @Override | |
| protected void setupBenchmark() throws Exception { | |
| // Custom setup logic if needed | |
| } | |
| @Override |
|
|
||
| System.out.printf("Setup comparison benchmark: %s format, %d rows%n", fileFormat, rowCount); | ||
| } | ||
|
|
Copilot
AI
Jan 16, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This method overrides AbstractBenchmark.tearDownTrial; it is advisable to add an Override annotation.
| @Override |
| private List<BenchmarkData> testDataList; | ||
| private MemoryProfiler memoryProfiler; | ||
| private List<ComparisonResult> localResults = new ArrayList<>(); | ||
|
|
Copilot
AI
Jan 16, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This method overrides AbstractBenchmark.setupTrial; it is advisable to add an Override annotation.
| @Override |
Overview
This PR introduces a comprehensive benchmark performance testing module for FastExcel, implementing the proposal outlined in #572.
Benchmark Results Available
CI Benchmark Run Completed Successfully: https://github.com/GOODBOY008/fastexcel/actions/runs/17709908635
Benchmark Artifacts: The workflow generated comprehensive benchmark reports available in the artifacts:
To view the benchmark reports:
benchmark-resultsartifact from: https://github.com/GOODBOY008/fastexcel/actions/runs/17709908635benchmark-reports/benchmark-comparison.htmlin your browserWhat's Changed
New Module: fastexcel-benchmark
• JMH Integration: Complete Maven configuration with industry-standard Java microbenchmarking framework
• Comprehensive Test Suites:
◦ Comparison benchmarks (FastExcel vs Apache POI)
◦ Memory efficiency specialized tests
◦ Streaming operation performance tests
◦ Microbenchmarks for core components
• Automated Execution: Multi-profile support with configurable dataset sizes and memory settings
• Advanced Features:
◦ Interactive CLI with scenario management
◦ Real-time memory profiling with GC tracking
◦ HTML visualization reports and JSON data export
◦ Performance trend analysis and regression detection
Key Components
Core Framework (
cn.idev.excel.benchmark.core)◦ Abstract benchmark base classes
◦ Configuration management
◦ Memory profiler integration
Test Scenarios (
cn.idev.excel.benchmark.*)◦ Read/Write operation benchmarks
◦ Fill operation performance tests
◦ Streaming benchmarks for large datasets
◦ Memory efficiency analysis
Comparison Benchmarks (
cn.idev.excel.benchmark.comparison)◦ Direct FastExcel vs Apache POI performance comparison
◦ Multi-dimensional analysis (throughput, latency, memory)
Utilities (
cn.idev.excel.benchmark.utils)◦ Test data generation
◦ File management utilities
◦ Reporting and visualization
Automated Scripts (
scripts/benchmark-runner.sh)◦ Profile-based execution (quick/standard/comprehensive)
◦ Configurable parameters and output formats
◦ Regression analysis automation
GitHub Actions Integration
• Workflow (
.github/workflows/benchmark.yml)◦ Manual trigger with
workflow_dispatchfor on-demand benchmarking◦ Java 11 setup with proper classpath resolution
◦ Automated artifact upload for benchmark results
◦ Fixed JMH forking issues for reliable results
Test Scenarios Coverage
• Data Scales: SMALL(1K) → MEDIUM(10K) → LARGE(100K) → EXTRA_LARGE(1M+)
• File Formats: XLSX
• Operation Types: Read, Write, Fill, Streaming
• Memory Analysis: Real-time monitoring, GC pressure analysis, allocation patterns
Benefits
Closes #572