Object Structure

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
01private void RunDifferentObjectsTest() 02 { 03 Configure(); 04 Init(); 05 System.Console.WriteLine("Storing " + _count + " objects with " + _depth + " levels of embedded objects:"); 06 07 Clean(); 08 System.Console.WriteLine(" - primitive object with int field"); 09 Open(); 10 StoreSimplest(); 11 Close(); 12 13 Open(); 14 System.Console.WriteLine(" - object with String field"); 15 Store(); 16 Close(); 17 18 Clean(); 19 Open(); 20 System.Console.WriteLine(" - object with StringBuilder field"); 21 StoreWithStringBuilder(); 22 Close(); 23 24 Clean(); 25 Open(); 26 System.Console.WriteLine(" - object with int array field"); 27 StoreWithArray(); 28 Close(); 29 30 Clean(); 31 Open(); 32 System.Console.WriteLine(" - object with ArrayList field"); 33 StoreWithArrayList(); 34 Close(); 35 }
InsertPerformanceBenchmark.cs: Configure
1private void Configure() 2 { 3 IConfiguration config = Db4oFactory.Configure(); 4 config.LockDatabaseFile(false); 5 config.WeakReferences(false); 6 config.Io(new MemoryIoAdapter()); 7 config.FlushFileBuffers(false); 8 }
InsertPerformanceBenchmark.cs: Init
1private void Init() 2 { 3 _count = 10000; 4 _depth = 3; 5 _isClientServer = false; 6 }
InsertPerformanceBenchmark.cs: StoreSimplest
01private void StoreSimplest() 02 { 03 StartTimer(); 04 for (int i = 0; i < _count; i++) 05 { 06 SimplestItem item = new SimplestItem(i, null); 07 for (int j = 1; j < _depth; j++) 08 { 09 item = new SimplestItem(i, item); 10 } 11 objectContainer.Set(item); 12 } 13 objectContainer.Commit(); 14 StopTimer("Store " + TotalObjects() + " objects"); 15 }
InsertPerformanceBenchmark.cs: Store
01private void Store() 02 { 03 StartTimer(); 04 for (int i = 0; i < _count; i++) 05 { 06 Item item = new Item("load", null); 07 for (int j = 1; j < _depth; j++) 08 { 09 item = new Item("load", item); 10 } 11 objectContainer.Set(item); 12 } 13 objectContainer.Commit(); 14 StopTimer("Store " + TotalObjects() + " objects"); 15 }
InsertPerformanceBenchmark.cs: StoreWithStringBuilder
01private void StoreWithStringBuilder() 02 { 03 StartTimer(); 04 for (int i = 0; i < _count; i++) 05 { 06 ItemWithStringBuilder item = new ItemWithStringBuilder(new StringBuilder("load"), null); 07 for (int j = 1; j < _depth; j++) 08 { 09 item = new ItemWithStringBuilder(new StringBuilder("load"), item); 10 } 11 objectContainer.Set(item); 12 } 13 objectContainer.Commit(); 14 StopTimer("Store " + TotalObjects() + " objects"); 15 }
InsertPerformanceBenchmark.cs: StoreWithArray
01private void StoreWithArray() 02 { 03 StartTimer(); 04 int[] array = new int[] { 1, 2, 3, 4 }; 05 for (int i = 0; i < _count; i++) 06 { 07 int[] id = new int[] { 1, 2, 3, 4 }; 08 ItemWithArray item = new ItemWithArray(id, null); 09 for (int j = 1; j < _depth; j++) 10 { 11 int[] id1 = new int[] { 1, 2, 3, 4 }; 12 item = new ItemWithArray(id1, item); 13 } 14 objectContainer.Set(item); 15 } 16 objectContainer.Commit(); 17 StopTimer("Store " + TotalObjects() + " objects"); 18 }
InsertPerformanceBenchmark.cs: StoreWithArrayList
01private void StoreWithArrayList() 02 { 03 StartTimer(); 04 ArrayList idList = new ArrayList(); 05 idList.Add(1); 06 idList.Add(2); 07 idList.Add(3); 08 idList.Add(4); 09 for (int i = 0; i < _count; i++) 10 { 11 ArrayList ids = new ArrayList(); 12 ids.AddRange(idList); 13 ItemWithArrayList item = new ItemWithArrayList(ids, null); 14 for (int j = 1; j < _depth; j++) 15 { 16 ArrayList ids1 = new ArrayList(); 17 ids1.AddRange(idList); 18 item = new ItemWithArrayList(ids1, item); 19 } 20 objectContainer.Set(item); 21 } 22 objectContainer.Commit(); 23 StopTimer("Store " + TotalObjects() + " objects"); 24 }
InsertPerformanceBenchmark.cs: SimplestItem
01public class SimplestItem 02 { 03 public int _id; 04 public SimplestItem _child; 05 06 public SimplestItem() 07 { 08 } 09 10 public SimplestItem(int id, SimplestItem child) 11 { 12 _id = id; 13 _child = child; 14 } 15 }
InsertPerformanceBenchmark.cs: ItemWithArray
01public class ItemWithArray 02 { 03 public int[] _id; 04 public ItemWithArray _child; 05 06 public ItemWithArray() 07 { 08 } 09 10 public ItemWithArray(int[] id, ItemWithArray child) 11 { 12 _id = id; 13 _child = child; 14 } 15 }
InsertPerformanceBenchmark.cs: ItemWithArrayList
01public class ItemWithArrayList 02 { 03 public ArrayList _ids; 04 public ItemWithArrayList _child; 05 06 public ItemWithArrayList() 07 { 08 } 09 10 public ItemWithArrayList(ArrayList ids, ItemWithArrayList child) 11 { 12 _ids = ids; 13 _child = child; 14 } 15 }
InsertPerformanceBenchmark.cs: ItemWithStringBuilder
01public class ItemWithStringBuilder 02 { 03 public StringBuilder _name; 04 public ItemWithStringBuilder _child; 05 06 public ItemWithStringBuilder() 07 { 08 } 09 10 public ItemWithStringBuilder(StringBuilder name, ItemWithStringBuilder child) 11 { 12 _name = name; 13 _child = child; 14 } 15 }

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