Use isEmpty em vez de equals
"A perfeição é feita de pequenos detalhes - não é apenas um detalhe." (Michelangelo)
Gostaria de começar esse post ressaltando a famosa frase de Michelangelo ditada acima que fala sobre "detalhes". Em minha busca por conhecimento dedico meu tempo justamente a isso, detalhes. Não basta para mim ter a solução em mãos, é preciso mais, é preciso saber como chegar até esta solução, cada detalhe da implementação de um algoritmo é o que o faz ter usabilidade, flexibilidade e clareza, porém nesse post quero tratar de algo mais interessante, um detalhe que envolve desempenho.
Assim como qualquer linguagem, Java tem seus detalhes de implementação que gosto de explorar. Nesse post quero mostrar o porque deve ser usado isEmpty() em vez de equals(""). Primeiramente vamos a documentação de ambos os métodos:
isEmpty - "Returns true if, and only if, length() is 0".
equals - "Compares this string to the specified object. The result is true if and only if the argument is not null and is a String object that represents the same sequence of characters as this object".
Pela documentação de cada método já temos uma simples noção de implementação onde que isEmpty utiliza um atributo privado para verificar se é igual a zero, apenas isso enquanto equals utiliza verificação de argumento nulo e sequencia de caracteres, o que com certeza é uma implementação mais penosa para um caso tão simples como a verificação de uma string vazia. Equals abrange verificação para casos mais complexos. Vamos ao código de cada método:
isEmpty
public boolean isEmpty() { return count == 0; }
equals
public boolean equals(Object anObject) { if (this == anObject) { return true; } if (anObject instanceof String) { String anotherString = (String) anObject; int n = count; if (n == anotherString.count) { char v1[] = value; char v2[] = anotherString.value; int i = offset; int j = anotherString.offset; while (n-- != 0) { if (v1[i++] != v2[j++]) return false; } return true; } } return false; }
Como esperado, o método equals é dedicado a comparação de strings diversas, enquanto o método isEmpty ataca um problema específico onde posso apenas querer saber se essa string esta vazia ou não.
Desempenho
Para o teste de desempenho fiz dois testes com jUnit, cada um atacando um dos métodos. Cada teste possui um loop de 100 milhões de iterações mostrando uma diferença de tempo considerável. Acredito que grandes empresas com sites que superam acessos de 1 milhão de pessoas rodando diversas classes contendo diversas vezes uma comparação utilizando equals("") resulte em algo semelhante, senão pior.
public class StringEmptyTest { @Test public void isEmpty() { String test = ""; for (int i = 0; i < 100000000; i++) { test.isEmpty(); } } @Test public void equals() { String test = ""; for (int i = 0; i < 100000000; i++) { test.equals(""); } } }
No resultado, isEmpty() foi 5,6 vezes menor em seu tempo de execução.
Conclusão
Quando Michelangelo cunhou sua frase, assim como tantas outras, o contexto era outro obviamente, mas programar não deixa de ser uma arte e assim como no contexto de Michelangelo, nós no nosso contexto precisamos entender o quanto um detalhe é importante. Com certeza utilizar isEmpty ou equals em um programa com poucos acessos não fará diferença, o que pretendo dizer com esse post é justamente o que a frase de Michelangelo diz "A perfeição é feita de pequenos detalhes...", junte esse detalhe, mais aquele outro e mais um e terá uma melhoria de desempenho.
1 comentários: