We have released recently Siaqodb 5.0 which has a new storage engine: LMDB. Besides many other things, our customers are using Siaqodb mainly because of performance. We compared Siaqodb 5.0 with SQLite and here are the results:

We’ll define first an entity to work with:


public class MyEntity
{
[SQLite.AutoIncrement, SQLite.PrimaryKey]
public int OID { get; set; }
public int IntValue { get; set; }
public string StringValue { get; set; }
public DateTime DateTimeValue { get; set; }
public Guid GuidValue { get; set; }
public double DoubleValue { get; set; }
}

Then we will make CRUD operations over Siaqodb and over SQLite.

Here is the INSERT code:

public static void Insert()
{
var entities = GetEntities().ToArray();
using (Siaqodb siaqodb = new Siaqodb())
{
siaqodb.Open(siaqodbPath, 100 * OneMB, 20);

Console.WriteLine("InsertSiaqodb...");
var stopwatch = new Stopwatch();
stopwatch.Start();

for (int i = 0; i < ENTITY_COUNT; i++)
{
siaqodb.StoreObject(entities[i]);
}

stopwatch.Stop();
Console.WriteLine("InsertSiaqodb took:" + stopwatch.Elapsed);

}

using (var dbsql = new SQLite.SQLiteConnection(sqLitePath))
{
dbsql.CreateTable();
Console.WriteLine("InsertSQLite...");
var stopwatch = new Stopwatch();
stopwatch.Start();

for (int i = 0; i < ENTITY_COUNT; i++)
{
dbsql.Insert(entities[i]);
}

stopwatch.Stop();
Console.WriteLine("InsertSQLite took:" + stopwatch.Elapsed);
}
}
//

And here is the result for ENTITY_COUNT=1000 and 10000:

insert

Now let’s compare UPDATE, here is the code:

public static void Update()
{
using (Siaqodb siaqodb = new Siaqodb())
{
siaqodb.Open(siaqodbPath, 100 * OneMB, 20);
var all = siaqodb.LoadAll();
Console.WriteLine("UpdateSiaqodb...");
var stopwatch = new Stopwatch();
stopwatch.Start();

foreach(MyEntity en in all)
{
en.IntValue++;
siaqodb.StoreObject(en);
}

stopwatch.Stop();
Console.WriteLine("UpdateSiaqodb took:" + stopwatch.Elapsed);

}

using (var dbsql = new SQLite.SQLiteConnection(sqLitePath))
{
var all = dbsql.Query("select * from MyEntity");

Console.WriteLine("UpdateSQLite...");
var stopwatch = new Stopwatch();
stopwatch.Start();
foreach (MyEntity en in all)
{
en.IntValue++;

dbsql.Update(en);
}

stopwatch.Stop();
Console.WriteLine("UpdateSQLite took:" + stopwatch.Elapsed);
}
}

And here is the result for ENTITY_COUNT=1000 and 10000:

update

No let’s compare READ, here is the code:

public static void Read()
{
using (Siaqodb siaqodb = new Siaqodb())
{
siaqodb.Open(siaqodbPath, 100 * OneMB, 20);
Console.WriteLine("ReadAllSiaqodb...");
var stopwatch = new Stopwatch();
stopwatch.Start();

var all = siaqodb.LoadAll();

stopwatch.Stop();
Console.WriteLine("ReadAllSiaqodb took:" + stopwatch.Elapsed);

}

using (var dbsql = new SQLite.SQLiteConnection(sqLitePath))
{
Console.WriteLine("ReadAllSQLite...");
var stopwatch = new Stopwatch();
stopwatch.Start();

var all = dbsql.Query("select * from MyEntity");

stopwatch.Stop();
Console.WriteLine("ReadAllSQLite took:" + stopwatch.Elapsed);
}
}

And here is the result for ENTITY_COUNT=10000 and 100000:

read

And finally let’s compare DELETE, here is the code:


public static void Delete()
{
using (Siaqodb siaqodb = new Siaqodb())
{
siaqodb.Open(siaqodbPath, 100 * OneMB, 20);
Console.WriteLine("DeleteSiaqodb...");
var all = siaqodb.LoadAll();
var stopwatch = new Stopwatch();
stopwatch.Start();
foreach(MyEntity en in all)
{
siaqodb.Delete(en);
}

stopwatch.Stop();
Console.WriteLine("DeleteSiaqodb took:" + stopwatch.Elapsed);

}

using (var dbsql = new SQLite.SQLiteConnection(sqLitePath))
{
Console.WriteLine("DeleteSQLite...");
var all = dbsql.Query("select * from MyEntity");

var stopwatch = new Stopwatch();
stopwatch.Start();
foreach (MyEntity en in all)
{
dbsql.Delete(en);
}
stopwatch.Stop();
Console.WriteLine("DeleteSQLite took:" + stopwatch.Elapsed);
}
}

And here is the result for ENTITY_COUNT=1000 and 10000:

delete

Source code is on GitHub, so you can run it yourself.

The tests were done on a machine with:

Processor: Intel i5-4200M @2.5 GHz
Memory: 4 GB
HardDisk: SSD Intel