O novo resultado? Incríveis `0,078 segundos`. 114 vezes mais rápido! E se você aumentar o tamanho dos laços dos testes, essa proporção só vai aumentar! Porque isso? O `contains` da `ArrayList` faz uma busca linear, já o `HashSet` utiliza uma tabela de espalhamento para tentar fazer a busca em tempo constante.
Você ainda pode fazer outros testes interessantes. Um `TreeSet` será mais devagar para inserir, pois mantém uma [árvore rubro negra](http://en.wikipedia.org/wiki/Red-black_tree) como estrutura de dados interna, e sua busca muito melhor que a da `ArrayList` e um pouco mais lenta que a do `HashSet`, porém teremos nossos elementos ordenados. Comparar a inserção e busca de elementos entre `LinkedList` e `ArrayList` também mostra números impressionantes: percorrer uma `LinkedList` sem usar um `Iterator` (ou enhanced for) é absurdamente lento, já que o seu método `get(int)` percorre a lista toda desde o começo, por sua vez, na `ArrayList` inserir elementos nas posições iniciais não é nada performático (é necessário deslocar todo o restante da array pra frente).
Obviamente uma [boa função de hash](https://blog.caelum.com.br/2006/09/04/ensinando-que-e-o-hashcode/) também é essencial. Recentemente a Sun [melhorou a função de hash dos nomes dos métodos](http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6393408) que o compilador utilizava para depois procurá-los, e com apenas isso conseguiu uma melhoria de performance de 2% na execução geral. Imagine se eles utilizassem uma `List` para isso? Dominar as coleções e estruturas de dados do Java é fundamental para um bom código.