Strange performance numbers
AlgorithmsAreCool opened this issue · comments
I have been looking at DBreeze recently and saw the great insert performance numbers. But I am getting very strange results from a pretty simple benchmark i wrote.
Here is my code
private static void Run(int runCount, string table, DBreezeEngine db)
{
Console.WriteLine("Testing " + runCount);
string simulatedRow = $@"C:\This\Is\A\Fake\Directory, {Guid.NewGuid()}, 0.00, 0, 2, 3";
var sw = Stopwatch.StartNew();
using (var t = db.GetTransaction())
{
for (int i = 0; i < runCount; i++)
t.Insert(table, i, simulatedRow);
t.Commit();
}
sw.Stop();
Console.WriteLine("Insert took {0:N2}. Rate = {1:N3}", sw.Elapsed.TotalMilliseconds, runCount / sw.Elapsed.TotalSeconds);
Console.WriteLine();
}
Starting with an empty directory (using on disk storage), i run the following
(Different tables for each test)
Run(100, "t1", db);
Run(1000, "t2", db);
Run(10000, "t3", db);
Run(100000, "t4", db);
Run(1000000, "t5", db);
and get
Testing 100
Insert took 110.10. Rate = 908.285
Testing 1000
Insert took 80.76. Rate = 12,381.984
Testing 10000
Insert took 113.05. Rate = 88,452.993
Testing 100000
Insert took 405.44. Rate = 246,645.924
Which is great!
But if i run (reusing the same table)
Run(100, "t1", db);
Run(1000, "t1", db);
Run(10000, "t1", db);
Run(100000, "t1", db);
My results are very different. The last test is about 66x slower.
Testing 100
Insert took 133.47. Rate = 749.257
Testing 1000
Insert took 309.03. Rate = 3,235.900
Testing 10000
Insert took 2,686.21. Rate = 3,722.711
Testing 100000
Insert took 26,852.87. Rate = 3,723.996
If find that if i delete the table in between each run the speed goes back to normal.
Is it known that multiple transaction against the same table cause this performance drop or am i seeing something strange?
Tested on Windows 8.1 x64, .Net 4.5.2, AnyCPU
Second time you make an update, that intends physically overwrite existing rows. To make batch update faster you have to switch table to a special mode. This switch concerns mostly big update-batches and mechanical hard drives.
Switch is called tran.Technical_SetTable_OverwriteIsNotAllowed("here table name");
Read more in documentation.
Ah i see. I will give that a shot.
Why is the Disk access not done with tran.Commit(); ?
Definitely, it is done :)
Doing an update with tran.Insert() is causing an disk access and is much slower.
Sure i can do tran.Technical_SetTable_OverwriteIsNotAllowed("here table name"); then an Update is fast like an Insert, but the Database file size is growing very fast.
There are a lot of options and possibilities. Please read documentation, find compromises.