Comprehensive performance comparison between SharpCoreDB, SQLite, and LiteDB.
This benchmark suite provides head-to-head performance comparisons across three popular .NET embedded databases:
- SharpCoreDB - High-performance embedded database with SIMD optimization
- SQLite - Industry-standard embedded database (memory and file modes)
- LiteDB - Popular .NET embedded NoSQL database
✅ Automatic README Updates - Results automatically inserted into root README.md ✅ Multiple Test Scenarios - INSERT, SELECT, UPDATE, DELETE, AGGREGATES operations ✅ Various Data Sizes - 1, 10, 100, 1K, 10K records ✅ Memory Diagnostics - Track allocations and GC pressure ✅ Performance Charts - Auto-generated charts using RPlot ✅ Statistical Analysis - Mean, median, standard deviation ✅ Encryption Impact - Compare encrypted vs unencrypted performance ✅ Fair Comparisons - Same data, same operations across all engines
cd SharpCoreDB.Benchmarks
dotnet run -c ReleaseThis will:
- Run all comparative benchmarks
- Generate detailed results
- Automatically update root README.md with results
- Copy charts to
docs/benchmarks/directory
# Insert benchmarks only
dotnet run -c Release -- --filter Insert
# Select benchmarks only
dotnet run -c Release -- --filter Select
# Update/Delete benchmarks only
dotnet run -c Release -- --filter Update
# Aggregate benchmarks only
dotnet run -c Release -- --filter AggregateTests single and bulk insert performance across different record counts.
Test Sizes: 1, 10, 100, 1,000 records
Scenarios:
- SharpCoreDB (encrypted) - Individual inserts
- SharpCoreDB (encrypted) - Batch inserts (prepared statements)
- SharpCoreDB (encrypted) - True batch inserts (single transaction)
- SharpCoreDB (no encryption) - Individual inserts
- SharpCoreDB (no encryption) - Batch inserts (prepared statements)
- SharpCoreDB (no encryption) - True batch inserts (single transaction)
- SQLite memory bulk insert (baseline)
- SQLite file bulk insert
- SQLite file + WAL + FullSync bulk insert
- LiteDB bulk insert
Example Results:
| Method | Records | Mean | Allocated |
|-----------------------------|---------|-------------|------------|
| SQLite_Memory_BulkInsert | 1000 | 12.5 ms | 128 KB |
| SharpCoreDB_BulkInsert | 1000 | 15.2 ms | 64 KB |
| LiteDB_BulkInsert | 1000 | 18.3 ms | 256 KB |
| SQLite_File_BulkInsert | 1000 | 22.1 ms | 128 KB |
Tests query performance for point queries, range filters, and full scans.
Database Size: 1,000 pre-populated records
Scenarios:
- Point query by ID
- Range query (age 25-35)
- Full table scan (active users)
Example Results:
| Method | Mean | Allocated |
|-----------------------------|-------------|------------|
| SQLite_PointQuery | 45 ?s | 256 B |
| LiteDB_PointQuery | 52 ?s | 512 B |
| SharpCoreDB_PointQuery | 68 ?s | 1 KB |
Tests modification and deletion performance.
Test Sizes: 1, 10, 100 records
Scenarios:
- Bulk updates
- Bulk deletes with repopulation
Example Results:
| Method | Records | Mean |
|-----------------------------|---------|-------------|
| SQLite_Update | 100 | 2.5 ms |
| LiteDB_Update | 100 | 3.2 ms |
| SharpCoreDB_Update | 100 | 4.1 ms |
Tests aggregate function performance across all database engines.
Database Size: 10,000 pre-populated records
Scenarios:
- COUNT(*) - Full table count
- COUNT(*) WHERE - Filtered count
- SUM(age) - Sum aggregation
- AVG(age) - Average calculation
- MIN(age) - Minimum value
- MAX(age) - Maximum value
- GROUP BY age - Grouping with count
- Complex aggregates - Multiple operations with filters
Databases Tested:
- SharpCoreDB (with AES-256-GCM encryption)
- SharpCoreDB (without encryption)
- SQLite (file-based)
- LiteDB (with manual LINQ aggregations)
Important Note on LiteDB Aggregates:
LiteDB doesn't have native SQL aggregate functions like SUM, AVG, MIN, MAX. The benchmarks use LINQ methods (FindAll().Sum(), etc.) which load all records into memory first, making them less efficient than true database-level aggregates. This is a fundamental limitation of LiteDB's architecture, not a benchmark design flaw.
Example Results:
| Method | Mean | Allocated |
|---------------------------------|-------------|------------|
| SQLite_CountAll | 125 ?s | 512 B |
| SharpCoreDB_NoEncrypt_CountAll | 180 ?s | 1 KB |
| SharpCoreDB_Encrypted_CountAll | 210 ?s | 1.2 KB |
| LiteDB_CountAll | 150 ?s | 768 B |
After running benchmarks, the following artifacts are generated:
SharpCoreDB.Benchmarks/
??? BenchmarkDotNet.Artifacts/
? ??? results/
? ? ??? *.html # HTML reports
? ? ??? *.csv # CSV data
? ? ??? *.json # JSON data
? ? ??? *.png # Performance charts
? ??? logs/
? ??? *.log # Execution logs
??? README.md # This file
SharpCoreDB/ (root)
??? README.md # ? AUTOMATICALLY UPDATED with results
??? docs/
??? benchmarks/
??? *.png # Copied charts
The benchmark suite automatically updates the root README.md with results.
- Run benchmarks: All scenarios execute with statistical analysis
- Collect results: BenchmarkResultAggregator gathers all summaries
- Generate markdown: Results formatted as markdown tables
- Update README: Section between
<!-- BENCHMARK_RESULTS -->markers is replaced - Copy charts: Performance charts copied to
docs/benchmarks/
<!-- BENCHMARK_RESULTS -->
## Benchmark Results (Auto-Generated)
**Generated**: 2024-12-15 10:30:45 UTC
### Executive Summary
| Operation | Winner | Performance Advantage |
|-----------|--------|----------------------|
| Bulk Insert (1K) | **SQLite** | 1.22x faster |
| Point Query | **SQLite** | 1.15x faster |
| Range Query | **LiteDB** | 1.08x faster |
| ...
### Detailed Results
...
<!-- /BENCHMARK_RESULTS -->To control where results appear in your README, add these markers:
# Your Project
## Some sections...
<!-- BENCHMARK_RESULTS -->
<!-- Results will be inserted here automatically -->
<!-- /BENCHMARK_RESULTS -->
## More sections...If markers don't exist, results are appended to the end of README.
Edit Infrastructure/BenchmarkConfig.cs:
AddJob(Job.Default
.WithWarmupCount(3) // Warmup iterations
.WithIterationCount(10) // Measurement iterations
.WithGcServer(true) // Server GC mode
.WithGcForce(true)); // Force GC between runsEdit Infrastructure/TestDataGenerator.cs:
public class UserRecord
{
public int Id { get; set; }
public string Name { get; set; }
public string Email { get; set; }
public int Age { get; set; }
public DateTime CreatedAt { get; set; }
public bool IsActive { get; set; }
}- Mean: Average execution time across all iterations
- Error: Standard error of the mean
- StdDev: Standard deviation (consistency of results)
- Allocated: Memory allocated per operation
- Rank: Performance ranking (1 = fastest)
SharpCoreDB Strengths:
- Low memory allocations (SIMD optimizations)
- Fast bulk operations (pooled buffers)
- Efficient page serialization
SQLite Strengths:
- Mature query optimizer
- Excellent B-tree performance
- Fast point queries with indexes
LiteDB Strengths:
- Simple API
- Good for document-style data
- Fast bulk operations
- Create benchmark class:
[Config(typeof(BenchmarkConfig))]
[MemoryDiagnoser]
public class MyNewBenchmarks
{
[Benchmark]
public void MyTest()
{
// Your benchmark code
}
}- Add to Program.cs:
var summary = BenchmarkRunner.Run<MyNewBenchmarks>(config);
aggregator.AddSummary(summary);- Run benchmarks:
dotnet run -c Releasename: Benchmarks
on:
push:
branches: [main]
schedule:
- cron: '0 0 * * 0' # Weekly
jobs:
benchmark:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Setup .NET
uses: actions/setup-dotnet@v3
with:
dotnet-version: '10.0.x'
- name: Run Benchmarks
run: |
cd SharpCoreDB.Benchmarks
dotnet run -c Release
- name: Commit README
run: |
git config --local user.email "action@github.com"
git config --local user.name "GitHub Action"
git add README.md docs/benchmarks/
git diff --quiet && git diff --staged --quiet || \
git commit -m "Update benchmark results [skip ci]"
git pushReduce test sizes in benchmark files:
[Params(1, 10, 100)] // Instead of 1, 10, 100, 1000, 10000
public int RecordCount { get; set; }Check:
- README.md exists in root directory
- Benchmark completed successfully
- No file permission errors in console output
Ensure RPlotExporter is working:
- Install R (optional, but recommended)
- Charts still generated as basic plots without R
As of December 2025 (.NET 10):
| Database | Insert (1K) | Query (10K) | Update (1K) | Memory |
|---|---|---|---|---|
| SQLite | ~12ms | ~45?s | ~2.5ms | 128KB |
| SharpCoreDB | ~15ms | ~68?s | ~4.1ms | 64KB |
| LiteDB | ~18ms | ~52?s | ~3.2ms | 256KB |
Results may vary based on hardware and configuration
To add new benchmark scenarios:
- Create benchmark class in
Comparative/directory - Follow existing patterns (setup, benchmark methods, cleanup)
- Add to
Program.csrunner - Update this README with description
- Run benchmarks to verify
- Submit PR with results
Same as SharpCoreDB project.
Note: Always run benchmarks on the same hardware for consistent comparisons. Results shown here are examples and will vary based on your environment.