Por fim, a melhor resposta é testá-lo. Faça um método que faça um loop sobre uma matriz vazia com e sem verificar o comprimento primeiro, chame cada 100.000 vezes e veja qual possui um tempo de execução mais rápido.
public void withCheck(Integer[] array) {
for (int i = 0; i < 100000; i++) {
if (array.length > 0) {
for (Integer i : array) {
// nothing to do.
}
}
}
}
public void withoutCheck(Integer[] array) {
for (int i = 0; i < 100000; i++) {
for (Integer i : array) {
// nothing to do.
}
}
}
public void test() {
long startTime = System.currentTimeMillis();
withCheck();
System.out.println("Time with check: " + (System.currentTimeMillis() - startTime) + "ms");
startTime = System.currentTimeMillis();
withoutCheck();
System.out.println("Time without check: " + (System.currentTimeMillis() - startTime) + "ms");
}
Quando escrevo código como esse, geralmente considero isso como um compromisso entre a legibilidade do código e o desempenho percebido ou potencial. Em outras palavras, adicionar uma verificação if (count > 0)
afeta negativamente a legibilidade, mesmo que por uma quantidade muito pequena. Então, qual é o ganho? Eu presumo que há pouca ou nenhuma vantagem, mas como você, eu não testei realmente. O que posso dizer é que, em todos os meus anos de criação de perfil, nunca encontrei um loop em um array vazio para ser um gargalo.
Tecnicamente, depende de como o iterador funciona. Para um loop foreach como você, você está criando um objeto iterador nos bastidores. Minha expectativa seria, e novamente, isso não é verificado, é que o objeto iterador FOR ARRAY seria simplesmente implementado assim (isto é Java, mas C # provavelmente é comparável):
public class ArrayIterator<T> implements Iterator<T> {
private int next = 0;
public T next() {
return backingArray[next++];
}
public boolean hasNext() {
return next < backingArray.length;
}
}
Portanto, iterar esse iterador deve sair muito rapidamente porque hasNext()
retornará false. Observe que é a mesma verificação que sua instrução if
faria.
Agora, se você estiver interagindo com uma lista vinculada, a implementação deve ser diferente. Se você verificar explicitamente o tamanho, talvez esteja forçando a verificação da lista vinculada. Em Java, LinkedList.size()
verifica uma variável explícita size
para que não passe na lista, mas não sei como o .NET a implementa.
Outra maneira de ver isso é a probabilidade de a coleção estar vazia? Se esse é um caso raro, então, se a teoria de iterar em um array vazio levar tempo for verdadeira, adicionar uma verificação explícita para empty first seria mais rápido se a coleção estivesse normalmente vazia. Se não, você está, teoricamente, desacelerando seu caso médio apenas para acelerar um pouco seu pior caso.
Mais uma vez, estas são todas as teorias e os tempos estão no nível micro, por isso leve-o com um grão de sal.
TL; DR
Depende do tipo de coleção, da plataforma de tempo de execução e do tamanho típico da coleção, mas, intuitivamente, parece improvável acelerar alguma coisa na maioria das situações. Mas a única maneira de saber com certeza é testá-lo.