segunda-feira, 15 de outubro de 2007

Ingenuidade versus desempenho

A ingenuidade de alguns programadores, relativamente à forma como as linguagens funcionam a baixo nível, trás muitas vezes impactos inesperados no desempenho das aplicações.
Vou mostrar um exemplo típico, que se encontra frequentemente em Javascript, uma função que usa um ciclo for para gerar uma lista de valores separados por virgulas.
function getValidZoneList()
{
var zoneList = '';

for( var i=0; i < arrValidZone.length; ++i )
{
if( zoneList == '' )
zoneList = arrValidZone[ i ][ 0 ];
else
zoneList += ', ' + arrValidZone[ i ][ 0 ];
}
return zoneList;
}

O primeiro problema com que nos deparamos é o teste
( zoneList == '' )
, que é tipicamente mais lento que testar
( zoneList.length == 0 )

O segundo problema é fazer testes desnecessários dentro dos ciclos!
Neste caso concreto o teste só é necessário, para determinar se precisamos de adicionar o separador virgula no caso de já termos algum elemento na lista. O facto é que este teste só é relevante no primeiro elemento, sendo falso para todos os restantes.

Se a função fosse implementada da forma que se sugere a seguir, aumentaria significativamente o seu desempenho, pois fariamos apenas um único test, no início:
// returns a comma separated String with the list of Valid Zones
function getValidZoneList()
{
var zoneList = '';

if( arrValidZone.length )
{
var i = 0;
zoneList += arrValidZone[ i ][ 0 ];

for( ++i; i < arrValidZone.length; ++i )
zoneList += ', ' + arrValidZone[ i ][ 0 ];
}
return zoneList;
}

1 comentário:

Tiago Sousa disse...

Por acaso nunca me tinha lembrado desta técnica, muito fixe ;)