Seguindo nosso último post, Testes de performance do Core Data sobre SQLite – Parte 2, quando iniciamos testes de desempenho com o Core Cata, agora continuaremos com os resultados desta análise.
Como definimos anteriormente este teste mostrará o desempenho em 4 situações (veja detalhes no post anterior):
- Inserções sem relacionamentos;
- Inserções com relacionamentos;
- Buscas sem relacionamentos;
- Buscas com relacionamentos.
O post anterior mostrou as 2 primeiras situações. Este post mostrará as últimas duas (selects).
1. Buscas sem relacionamentos
Este teste tenta executar buscas sem joins de 2 formas:
- Busca por atributo;
- Busca por identificador.
Em cada caso, vemos como o tempo para executar a busca varia com o número de registros da tabela (de 1 até 10000):
a) Busca por atributo

| mín | 0,007469 s |
| máx | 0,259504 s |
| média | 0,049227 s |
| total | 492,3 s |
Como podemos ver no gráfico, quando buscando por um atributo que não esteja indexado o tempo necessário para executar o select varia quase linearmente com o número de registros da tabela. Assim, é fácil pensar em como o desempenho de sua tabela está piorando com o tempo.
b) Busca por identificador

| mín | 0,000070 s |
| máx | 0,004420 s |
| média | 0,000086 s |
| total | 0,8597 s |
Este caso mostra que buscando pelo identificador (indexado), o tempo de busca praticamente não muda com o aumento do número de registros da tabela, uma vez que o tempo médio de busca foi quase igual ao tempo mínimo.
Conclusão
Estes testes resultaram na seguinte tabela:
| Teste | Tempo Médio por Select | Tempo Total |
| Busca por atributo | t1 or 0,049227 s | t2 or 492,3 s |
| Busca por identificador | 0,0017 x t1 or 0,000086 s | 0,0017 x t2 or 0,8597 s |
Como podemos ver, para selects simples (sem joins) sempre que possível devemos usar identificadores para a busca, mas, se precisarmos buscar pelo identificador, não é difícil pensar no desempenho, uma vez que ele aumenta linearmente com o tamanho da tabela.
2. Buscas com relacionamentos
Este teste mostra como o tempo para executar um select aumenta com o número de joins (em cada select) e o número de linhas. O número de joins varia de 0 a 4.
a) Relacionamentos: 0

| mín | 0,010763 s |
| máx | 0,405039 s |
| média | 0,071537 s |
| total | 7,15 s |
Este teste não tem relacionamentos, então o resultado é o mesmo do teste anterior quando buscando por um atributo.
b) Relacionamentos: 1

| mín | 0,012153 s |
| máx | 0,632435 s |
| média | 0,299673 s |
| total | 29,98 s |
Como esperado, com 1 join o tempo médio foi bem maior, 4,27 vezes maior que com 0 joins.
c) Relacionamentos: 2

| mín | 0,021038 s |
| máx | 0,633293 s |
| média | 0,29986 s |
| total | 29,96 s |
Com 2 joins precisamos de quase o mesmo tempo de processar o select, como esperado, uma vez que a engine de busca já entrou o passo de join do processo de busca, o que não ocorre com 0 joins.
d) Relacionamentos: 3

| mín | 0,025723 s |
| máx | 0,621014 s |
| média | 0,303619 s |
| total | 30,36 s |
Com 3 joins o tempo médio foi levemente pior novamente, como esperado.
e) Relacionamentos: 4

| mín | 0,027883 s |
| máx | 0,64675 s |
| média | 0,316077 s |
| total | 31,61 s |
Novamente, com 4 joins o tempo médio foi levemente pior, como esperado.
Conclusão
A seguinte tabela resulta dos testes:
| Teste | Tempo Médio | Tempo Total |
| 0 joins | 0,071537 s | 7,15 s |
| 1 join | 0,299673 s | 29,98 s |
| 2 joins | 0,29986 s | 29,96 s |
| 3 joins | 0,303619 s | 30,36 s |
| 4 joins | 0,316077 s | 31,61 s |
Como podemos ver, temos uma grande variação de 0 para 1 join, mas uma pequena variação conforme o número de joins aumenta, devido a funcionamento da engine de busca.
Este post, e o anterior, mostraram os testes de desempenho para o Core Data, que nos trouxeram informações para analisar quando usá-lo em um project e qual impacto teríamos quando usando-o.
Os próximos posts apresentarão nossa análise sobre o framework Magical Panda Active Record. Esperamos que você esteja ansioso como nós estamos.
Este post também está disponível em Inglês: Core Data over SQLite Performance Tests – Part 3