paulo1205
(usa Ubuntu)
Enviado em 16/12/2014 - 15:57h
Caro renato_pacheco,
Permita-me comentar sua sugestão.
renato_pacheco escreveu:
Cara, é muito simples. Basta vc por uma condição:
#!/bin/bash
for i in $(seq 1 10)
do
if [ `expr $i % 2` == 0 ]
then
echo $i
fi
done
Minha primeira observação é que sua sugestão não faz exatamente o que ele pediu, que é contar de 2 em 2 ou
n em
n. Você continua contando de 1 em 1, mas ignora alguns deles. É um jeito de fazer? É, mas imagine contar de 0 a 1 bilhão, de 100 milhões em 100 milhões. Você teria que contar 1.000.000.001 valores diferentes para imprimir apenas 11. Não acha um pouco ineficiente?
Outro ponto é que, mesmo tendo eu mesmo oferecido como opção para o nosso colega, eu acho um desperdício usar o comando
seq para gerar previamente uma lista de valores. Quando possível, eu procuro evitar comandos externos (mais detalhes abaixo), mas o problema maior é que algo do tipo
for i in $(seq 1 10)
tem de ser expandido pelo shell em
for i in 1 2 3 4 5 6 7 8 9 10
antes do laço de repetição começar a ser utilizado. Esses valores preconhecidos, que serão sequencialmente atribuídos à variável de controle, ocupam espaço em memória no processo do shell. Se a quantidade de valores for pequena, esse efeito é pouco expressivo, mas num caso maior, isso pode começar a pesar bastante. Num exemplo extremo, como o que eu sugeri acima, de um laço superineficiente com mais de um bilhão de valores, isso pode até esgotar a memória da máquina.
Dentro do laço, você tem um comando
if para fazer a seleção de valores. Esse comando chama o comando externo
[ (que fica em
/usr/bin/[) para testar uma condição de igualdade que tem um dos termos que depende também da execução de outro comando externo (
expr). Esses comandos são executados uma vez
para cada valor da variável de controle do laço de repetição. Isso é muito ineficiente, porque cada execução de cada comando externo implica a criação de um novo processo filho do shell, a execução nesse filho do comando requisitado (que envolve a carga do programa do disco para a memória, seguida da análise e carga de suas bibliotecas dinâmicas, e a execução do programa propriamente dito, depois de carregado para a memória), seguida de sua terminação, com a liberação de tudo o fora carregado para a memória e de outros recursos, e, por fim, a liberação do processo filho, depois que o shell reconhecer sua terminação. Por mais que o uso de
caches acelere algumas dessas etapas, elas ainda existem.