More complex objects are usually more difficult not only to store, but also to query and instantiate. The following test demonstrates how query performance depends on class structure, complexity and depth:
QueryPerformanceBenchmark.cs: RunDifferentObjectsTest private void RunDifferentObjectsTest() { Init(); System.Console.WriteLine("Storing " + _count + " objects with " + _depth + " levels of embedded objects:"); Clean(); System.Console.WriteLine(); System.Console.WriteLine(" - primitive object with int field"); Open(Configure()); StoreSimplest(); objectContainer.Ext().Purge(); Close(); Open(Configure()); StartTimer(); IQuery query = objectContainer.Query(); query.Constrain(typeof(SimplestItem)); query.Descend("_id").Constrain(1); IList result = query.Execute(); SimplestItem simplestItem = (SimplestItem)result[0]; StopTimer("Querying SimplestItem: " + simplestItem._id); Close(); Open(Configure()); System.Console.WriteLine(); System.Console.WriteLine(" - object with string field"); Store(); objectContainer.Ext().Purge(); Close(); Open(Configure()); StartTimer(); query = objectContainer.Query(); query.Constrain(typeof(Item)); query.Descend("_name").Constrain("level1/2"); result = query.Execute(); Item item = (Item)result[0]; StopTimer("Querying object with string field: " + item._name); Close(); Clean(); Open(Configure()); System.Console.WriteLine(); System.Console.WriteLine(" - object with StringBuilder field"); StoreWithStringBuffer(); objectContainer.Ext().Purge(); Close(); Open(Configure()); StartTimer(); query = objectContainer.Query(); query.Constrain(typeof(ItemWithStringBuilder)); query.Descend("_name").Constrain(new StringBuilder("level1/2")); result = query.Execute(); ItemWithStringBuilder itemWithSB = (ItemWithStringBuilder)result[0]; StopTimer("Querying object with StringBuilder field: " + itemWithSB._name); Close(); Clean(); Open(Configure()); System.Console.WriteLine(); System.Console.WriteLine(" - object with int array field"); StoreWithArray(); objectContainer.Ext().Purge(); Close(); Open(Configure()); StartTimer(); query = objectContainer.Query(); query.Constrain(typeof(ItemWithArray)); IQuery idQuery = query.Descend("_id"); idQuery.Constrain(1); idQuery.Constrain(2); idQuery.Constrain(3); idQuery.Constrain(4); result = query.Execute(); ItemWithArray itemWithArray = (ItemWithArray)result[0]; StopTimer("Querying object with Array field: [" + itemWithArray._id[0] + ", " + +itemWithArray._id[1] + ", " + +itemWithArray._id[2] + ", " + +itemWithArray._id[0] + "]"); Close(); Clean(); Open(Configure()); System.Console.WriteLine(); System.Console.WriteLine(" - object with ArrayList field"); StoreWithArrayList(); objectContainer.Ext().Purge(); Close(); Open(Configure()); StartTimer(); query = objectContainer.Query(); query.Constrain(typeof(ItemWithArrayList)); query.Descend("_ids").Constrain(1).Contains(); result = query.Execute(); ItemWithArrayList itemWithArrayList = (ItemWithArrayList)result[0]; StopTimer("Querying object with ArrayList field: " + itemWithArrayList._ids.ToString()); Close(); }
QueryPerformanceBenchmark.cs: Init private void Init() { _filePath = "performance.db4o"; // amount of objects _count = 10000; // depth of objects _depth = 3; _isClientServer = false; }
QueryPerformanceBenchmark.cs: Configure private IConfiguration Configure() { IConfiguration config = Db4oFactory.NewConfiguration(); return config; }
QueryPerformanceBenchmark.cs: SimplestItem public class SimplestItem { public int _id; public SimplestItem _child; public SimplestItem() { } public SimplestItem(int id, SimplestItem child) { _id = id; _child = child; } }
QueryPerformanceBenchmark.cs: ItemWithStringBuilder public class ItemWithStringBuilder { public StringBuilder _name; public ItemWithStringBuilder _child; public ItemWithStringBuilder() { } public ItemWithStringBuilder(StringBuilder name, ItemWithStringBuilder child) { _name = name; _child = child; } }
QueryPerformanceBenchmark.cs: ItemWithArray public class ItemWithArray { public int[] _id; public ItemWithArray _child; public ItemWithArray() { } public ItemWithArray(int[] id, ItemWithArray child) { _id = id; _child = child; } }
QueryPerformanceBenchmark.cs: ItemWithArrayList public class ItemWithArrayList { public ArrayList _ids; public ItemWithArrayList _child; public ItemWithArrayList() { } public ItemWithArrayList(ArrayList ids, ItemWithArrayList child) { _ids = ids; _child = child; } }
Results from the test machine:
- primitive object with int field
Store 30000 objects: 1878ms
Querying SimplestItem: 1: 425ms
- object with String field
Store 30000 objects: 2599ms
Querying object with String field: level1/2: 436ms
- object with StringBuffer field
Store 30000 objects: 5658ms
Querying object with StringBuffer field: level1/2: 3489ms
- object with int array field
Store 30000 objects: 2487ms
Querying object with Array field: [1, 2, 3, 1]: 1777ms
- object with ArrayList field
Store 30000 objects: 5302ms
Querying object with ArrayList field: [1, 2, 3, 4]: 3796ms
Download example code: