Para começar, você precisa entender que os shell scripts são apenas um atalho conveniente para digitar os comandos. Toda vez que você ou um script chama grep
, você não está chamando uma primitiva integrada; você está pedindo ao shell para procurar um programa chamado grep
e iniciá-lo como um novo processo. A criação de um novo processo e a execução do primeiro bit de código é provavelmente a coisa menos previsível que você pode fazer em qualquer ambiente que não esteja ajustado para a previsibilidade. Esse será o caso de qualquer computador que esteja executando um sistema operacional que não seja em tempo real. Os detalhes de por que isso seria forrageiro para metade de uma classe semestral em sistemas operacionais, mas posso dar um exemplo ou dois que ilustrem por que seus esforços para medir com precisão as execuções completas do programa não produzirão os resultados consistentes que você pensa eles deveriam.
A primeira coisa que a maioria dos programas faz quando recebe a CPU pela primeira vez é gerar uma falha de página para que o código de primeira página possa ser carregado. Se uma dúzia de outros programas estiverem fazendo E / S no mesmo dispositivo em que o código mora, o tempo que as páginas do seu programa demoram para carregar depende de quão longe estão as solicitações na fila do dispositivo. Você pode pensar que seu programa de teste está funcionando sozinho, mas eu apostaria dólares em donuts que não é. (Também vale a pena mencionar que grep
é um programa pesado de I / O, então quanto tempo leva para ler a entrada varia por muitas das mesmas razões.)
Muitos sistemas operacionais tomam medidas para evitar que cópias redundantes do mesmo código permaneçam ao mesmo tempo, como uma maneira de reduzir o consumo de memória e aumentar o desempenho. Isso significa que, se você iniciar grep
e houver outro grep
em execução com sua primeira página já residente, a falha de página mencionada nunca acontecerá e todo esse esforço será ignorado. Isso diminui o tempo de execução do relógio de parede.
No momento em que você começa a fazer um timeit
no MATLAB, o processo do MATLAB já está em execução e é provável que ele tenha passado pelos aros necessários para carregar sua função antes de invocá-la repetidamente. A invocação acontece com bastante rapidez porque é apenas uma chamada interna. Embora também haja muitos fatores que afetariam o tempo que leva timeit
para ser executado, eles se aplicam igualmente a qualquer outra coisa.
Dito isso, acho que a verdadeira razão para o que você está vendo é que a comparação não é do mesmo jeito.
O time(1)
do Unix executa o programa sendo testado exatamente uma vez, onde o timeit
do MATLAB multiplicou a função que você está testando várias vezes e retorna a mediana dos resultados. A documentação sugere que as funções timeit
e tic
e toc
não devem ser usadas juntas, o que sugere que as últimas são usadas pela primeira. Os documentos para tic
e toc
recomendam que, se você tiver um código que seja executado em menos de 0,1 segundo, execute-o várias vezes e calcule uma média. O que eu tomo disso é que o tempo do MATLAB é duas ordens de grandeza menos preciso do que o de time(1)
e se destina mais a verificar quanto tempo você pode se livrar das funções de longa duração. Isso e a combinação da média e da mediana, dada amostras suficientes, empurram muita variação para um resultado bastante consistente.