Comparison of SQLite and LinksPlatform's Doublets (links) on basic embeded database operations with objects (create list, read list, delete list).
Based on examples from https://github.com/FahaoTang/dotnetcore-examples and https://github.com/Konard/LinksPlatform
SQLite
using System.Linq; using Comparisons.SQLiteVSDoublets.Model; namespace Comparisons.SQLiteVSDoublets.SQLite { public class SQLiteTestRun : TestRun { public SQLiteTestRun(string dbFilename) : base(dbFilename) { } public override void Prepare() { using var dbContext = new SQLiteDbContext(DbFilename); dbContext.Database.EnsureCreated(); } public override void CreateList() { using var dbContext = new SQLiteDbContext(DbFilename); dbContext.BlogPosts.AddRange(BlogPosts.List); dbContext.SaveChanges(); } public override void ReadList() { using var dbContext = new SQLiteDbContext(DbFilename); foreach (var blogPost in dbContext.BlogPosts) { ReadBlogPosts.Add(blogPost); } } public override void DeleteList() { using var dbContext = new SQLiteDbContext(DbFilename); var blogPostsToDelete = dbContext.BlogPosts.ToList(); dbContext.BlogPosts.RemoveRange(blogPostsToDelete); dbContext.SaveChanges(); } } }
Doublets
using System.IO; using Platform.IO; using Comparisons.SQLiteVSDoublets.Model; namespace Comparisons.SQLiteVSDoublets.Doublets { public class DoubletsTestRun : TestRun { public string DbIndexFilename { get; } public DoubletsTestRun(string dbFilename) : base(dbFilename) => DbIndexFilename = $"{Path.GetFileNameWithoutExtension(dbFilename)}.links.index"; public override void Prepare() { using var dbContext = new DoubletsDbContext(DbFilename, DbIndexFilename); } public override void CreateList() { using var dbContext = new DoubletsDbContext(DbFilename, DbIndexFilename); foreach (var blogPost in BlogPosts.List) { dbContext.SaveBlogPost(blogPost); } } public override void ReadList() { using var dbContext = new DoubletsDbContext(DbFilename, DbIndexFilename); foreach (var blogPost in dbContext.BlogPosts) { ReadBlogPosts.Add(blogPost); } } public override void DeleteList() { using var dbContext = new DoubletsDbContext(DbFilename, DbIndexFilename); var blogPostsToDelete = dbContext.BlogPosts; foreach (var blogPost in blogPostsToDelete) { dbContext.Delete((uint)blogPost.Id); } } protected override void DeleteDatabase() { File.Delete(DbFilename); File.Delete(DbIndexFilename); } protected override long GetDatabaseSizeInBytes() => FileHelpers.GetSize(DbFilename) + FileHelpers.GetSize(DbIndexFilename); } }
Result
Performance
Disk usage
RAM usage
Source data
BenchmarkDotNet=v0.12.0, OS=Windows 10.0.18362 Intel Core i7-6700K CPU 4.00GHz (Skylake), 1 CPU, 8 logical and 4 physical cores .NET Core SDK=3.0.100 [Host] : .NET Core 3.0.0 (CoreCLR 4.700.19.46205, CoreFX 4.700.19.46214), X64 RyuJIT Job-AYEMIX : .NET Core 3.0.0 (CoreCLR 4.700.19.46205, CoreFX 4.700.19.46214), X64 RyuJIT InvocationCount=1 IterationCount=1 UnrollFactor=1 WarmupCount=2
| Method | N | Mean | Error | Gen 0 | Gen 1 | Gen 2 | Allocated | SizeAfterCreation |
|---|---|---|---|---|---|---|---|---|
| SQLite | 1000 | 719.1 ms | NA | 5000.0000 | - | - | 30.67 MB | 925696 |
| Doublets | 1000 | 145.0 ms | NA | 34000.0000 | 1000.0000 | - | 139.37 MB | 767616 |
| SQLite | 10000 | 2,770.3 ms | NA | 64000.0000 | 19000.0000 | - | 315.71 MB | 9056256 |
| Doublets | 10000 | 1,003.8 ms | NA | 304000.0000 | 31000.0000 | - | 1220.55 MB | 6528256 |
| SQLite | 100000 | 35,853.8 ms | NA | 680000.0000 | 151000.0000 | - | 3234.09 MB | 90890240 |
| Doublets | 100000 | 13,083.4 ms | NA | 3088000.0000 | 328000.0000 | - | 12356.33 MB | 64192256 |
Conclusion
In this particular comparison, Doublets are faster and use less memory on disk, but this comes with the cost of additional use of RAM (Sqlite uses it less).



