Object Structure naturally has a major influence on insert performance: inserting one object, which is a linked list of 1000 members, is much slower than inserting an object with a couple of primitive fields.
The following test compares storing time of similar objects with one different field:
InsertPerformanceBenchmark.cs: RunDifferentObjectsTest
private void RunDifferentObjectsTest()
{
Configure();
Init();
System.Console.WriteLine("Storing " + _count + " objects with "
+ _depth + " levels of embedded objects:");
Clean();
System.Console.WriteLine(" - primitive object with int field");
Open();
StoreSimplest();
Close();
Open();
System.Console.WriteLine(" - object with String field");
Store();
Close();
Clean();
Open();
System.Console.WriteLine(" - object with StringBuilder field");
StoreWithStringBuilder();
Close();
Clean();
Open();
System.Console.WriteLine(" - object with int array field");
StoreWithArray();
Close();
Clean();
Open();
System.Console.WriteLine(" - object with ArrayList field");
StoreWithArrayList();
Close();
}
InsertPerformanceBenchmark.cs: Configure
private void Configure()
{
IConfiguration config = Db4oFactory.Configure();
config.LockDatabaseFile(false);
config.WeakReferences(false);
config.Io(new MemoryIoAdapter());
config.FlushFileBuffers(false);
}
InsertPerformanceBenchmark.cs: Init
private void Init()
{
_count = 10000;
_depth = 3;
_isClientServer = false;
}
InsertPerformanceBenchmark.cs: StoreSimplest
private void StoreSimplest()
{
StartTimer();
for (int i = 0; i < _count; i++)
{
SimplestItem item = new SimplestItem(i, null);
for (int j = 1; j < _depth; j++)
{
item = new SimplestItem(i, item);
}
objectContainer.Store(item);
}
objectContainer.Commit();
StopTimer("Store " + TotalObjects() + " objects");
}
InsertPerformanceBenchmark.cs: Store
private void Store()
{
StartTimer();
for (int i = 0; i < _count; i++)
{
Item item = new Item("load", null);
for (int j = 1; j < _depth; j++)
{
item = new Item("load", item);
}
objectContainer.Store(item);
}
objectContainer.Commit();
StopTimer("Store " + TotalObjects() + " objects");
}
InsertPerformanceBenchmark.cs: StoreWithStringBuilder
private void StoreWithStringBuilder()
{
StartTimer();
for (int i = 0; i < _count; i++)
{
ItemWithStringBuilder item = new ItemWithStringBuilder(
new StringBuilder("load"), null);
for (int j = 1; j < _depth; j++)
{
item = new ItemWithStringBuilder(new StringBuilder("load"), item);
}
objectContainer.Store(item);
}
objectContainer.Commit();
StopTimer("Store " + TotalObjects() + " objects");
}
InsertPerformanceBenchmark.cs: StoreWithArray
private void StoreWithArray()
{
StartTimer();
int[] array = new int[] { 1, 2, 3, 4 };
for (int i = 0; i < _count; i++)
{
int[] id = new int[] { 1, 2, 3, 4 };
ItemWithArray item = new ItemWithArray(id, null);
for (int j = 1; j < _depth; j++)
{
int[] id1 = new int[] { 1, 2, 3, 4 };
item = new ItemWithArray(id1, item);
}
objectContainer.Store(item);
}
objectContainer.Commit();
StopTimer("Store " + TotalObjects() + " objects");
}
InsertPerformanceBenchmark.cs: StoreWithArrayList
private void StoreWithArrayList()
{
StartTimer();
ArrayList idList = new ArrayList();
idList.Add(1);
idList.Add(2);
idList.Add(3);
idList.Add(4);
for (int i = 0; i < _count; i++)
{
ArrayList ids = new ArrayList();
ids.AddRange(idList);
ItemWithArrayList item = new ItemWithArrayList(ids, null);
for (int j = 1; j < _depth; j++)
{
ArrayList ids1 = new ArrayList();
ids1.AddRange(idList);
item = new ItemWithArrayList(ids1, item);
}
objectContainer.Store(item);
}
objectContainer.Commit();
StopTimer("Store " + TotalObjects() + " objects");
}
InsertPerformanceBenchmark.cs: SimplestItem
public class SimplestItem
{
public int _id;
public SimplestItem _child;
public SimplestItem()
{
}
public SimplestItem(int id, SimplestItem child)
{
_id = id;
_child = child;
}
}
InsertPerformanceBenchmark.cs: ItemWithArray
public class ItemWithArray
{
public int[] _id;
public ItemWithArray _child;
public ItemWithArray()
{
}
public ItemWithArray(int[] id, ItemWithArray child)
{
_id = id;
_child = child;
}
}
InsertPerformanceBenchmark.cs: ItemWithArrayList
public class ItemWithArrayList
{
public ArrayList _ids;
public ItemWithArrayList _child;
public ItemWithArrayList()
{
}
public ItemWithArrayList(ArrayList ids, ItemWithArrayList child)
{
_ids = ids;
_child = child;
}
}
InsertPerformanceBenchmark.cs: ItemWithStringBuilder
public class ItemWithStringBuilder
{
public StringBuilder _name;
public ItemWithStringBuilder _child;
public ItemWithStringBuilder()
{
}
public ItemWithStringBuilder(StringBuilder name, ItemWithStringBuilder child)
{
_name = name;
_child = child;
}
}
The following results were achieved for the testing configuration:
.NET:
Storing 10000 objects with 3 levels of embedded objects:
- primitive object with int field
Store 30000 objects: 1123ms
- object with String field
Store 30000 objects: 1356ms
- object with StringBuilder field
Store 30000 objects: 4982ms
- object with int array field
Store 30000 objects: 1810ms
- object with ArrayList field
Store 30000 objects: 3479ms
Download example code: