Following the last post, Core Data over SQLite Performance Tests – Part 1, when we introduced Core Data and defined the environment in which tests will run on, now we are going to start presenting you the results of this analysis.
As we defined before, this test will show the performance of 4 situations (see details on the previous post):
- Insert without join tables;
- Inserts with tables;
- Select without join tables;
- Select with join tables.
This post will cover the first 2 situations (inserts).
1. Inserts without join tables
This test tries to execute 10000 inserts on 5 different ways:
- Batch size: 1; Times: 10000;
- Batch size: 10; Times: 1000;
- Batch size: 100; Times: 100;
- Batch size: 1000; Times: 10;
- Batch size: 10000; Times: 1.
The results were the following:
a) Batch size: 1; Times: 10000

| min | 0.037017 s |
| max | 0.571604 s |
| average | 0.047213 s |
| total | 417.3 s |
As we can see on the chart, we have a slight variance between the inserts. Although the maximum chart value was 0.57 seconds, the average (0.047s) was much more close to the minimum value (0.037s). Also, we can see that the time needed to a insert does not changes significantly while the table increases.
b) Batch size: 10; Times: 1000

| min | 0.051545 s |
| max | 1.592167 s |
| average | 0.077328 s |
| total | 77.3 s |
This case shown us that, increasing the batch size to 10 we need, on average, about 1.64x more time to execute this batch. So, we can imagine that is much better to execute a big batch than lot of small batches. The test shown that to insert 10000 registries with batch size of 10 we needed 77.3 s, while with batch size of 1, to insert 10000 registries we needed 417.3 s.
c) Batch size: 100; Times: 100

| min | 0.221817 s |
| max | 0.733436 s |
| average | 0.276504 s |
| total | 27.7 s |
This case shown that increasing again the batch size, now to 100, we needed about 3.6x more time per batch than we needed with batch size of 10. So, we can deduce that the time per batch does not increases linearly as the batch size increases. But again, the total time to execute 10000 inserts was lower (27 s against 77 s).
d) Batch size: 1000; Times: 10

| min | 2.341496 s |
| max | 2.895445 s |
| average | 2.522845 s |
| total | 25.2 s |
Again, the same happened. As we increases the batch size to 1000 we needed 9.1x more time than we needed with batch size of 100. The total time was better than the previous, but is almost the same (25 s against 27 s).
e) Batch size: 10000; Times: 1 (10 repetitions with empty database)

| min | 19.171194 s |
| max | 24.020913 s |
| average | 22.2 s |
This time, increasing the batch size to 10000 we needed 8x more time than we needed with batch size of 1000, while we could imagine we would need more than 9.1. So, we needed only 22 s to execute 10000 inserts.
Conclusion
This tests resulted on the following table:
| Test | Average Time per Batch | Total Time |
| a | t1 or 0.047213 s | t2 or 417.3 s |
| b | 1.83 x t1 or 0.077328 s | t2/5.40 or 77.3 s |
| c | 5.86 x t1 or 0.276504 s | t2/0.066 or 27.7 s |
| d | 53.68 x t1 or 2.523 s | t2/0.060 or 25.2 s |
| e | 470.34 x t1 or 22.2 s | t2/0.053 or 22.2 s |
As we can see, for simple inserts (without joins) as we increases the batch size, the time needed to to execute that batch is greater, but, the total time is lower. So, with Core Data, when possible we should save data to database using batches.
2. Inserts with join tables
This test shows how the time to execute a insert increases as the number of join tables (in each insert) and number of rows increases. The number of joins varies from 0 to 3.
a) Joins quantity: 0

| min | 0.053622 s |
| max | 0.626013 s |
| average | 0.068631 s |
| total | 137.3 s |
This test has no joins, so the results is the same from the previous test.
b) Joins quantity: 1

| min | 0.617910 s |
| max | 0.353416 s |
| average | 0.080156 s |
| total | 160.3 s |
As might be expected, with 1 join the average time to a insert was 1.17 times greater than with 0 joins.
c) Joins quantity: 2

| min | 0.078214 s |
| max | 0.559592 s |
| average | 0.109143 s |
| total | 218.3 s |
With 2 joins we needed even more time to process an insert: 1.37 times more than with 1 join. Also, we can see that it seems that, as the database increases, we need more time to do inserts that was join tables.
d) Joins quantity: 3

| min | 0.093524 s |
| max | 0.650233 s |
| average | 0.135843 s |
| total | 271.7 s |
With 3 joins the average time was worst again: 1.244 times more than with 2 joins.
Conclusion
The following table results from the tests:
| Test | Average Time | Total Time |
| a | t1 or 0.068631 s | t2 or 137.3 s |
| b | 1.17 x t1 or 0.080156 s | 1.17 x t2 or 160.3 s |
| c | 1.59 x t1 or 0.109143 s | 1.59 x t2 or 218.3 s |
| d | 1.99 x t1 or 0.135843 s | 1.99 x t2 or 271.7 s |
As we can see, as the number of joins increases in a insert the time required to process it also increases. This increasing number is not linear.
The next post will present our results and conclusions for selects on Core Data, stay tuned!
This post is also available in Portuguese: Testes de performance do Core Data sobre SQLite – Parte 2