sábado, 25 de julho de 2009

Triângulo de pascal em ActionScript 3

Olá pessoal! Estava tirando a poeira dos meus conhecimentos de as3 e implementei um código que reproduz o triângulo de pascal (Link).
Acho que ele não está muito difícil de entender. A classe PascalsTriangle recebe recebe um número de linhas que vão ser calculadas e retorna um array de arrays. Cada um destes arrays retornados é uma linha do triângulo. A classe Main chama os métodos na classe PascalsTriangle e exibe os valores no stage no formato de um triangulo. Se quiser alterar o tamanho do triângulo basta alterar a constante NUMBER_OF_ROWS na classe Main.as.
Eu compilei o arquivo usando o flex mas deve funcionar no flash também, embora você deva retirar a seguinte linha do arquivo Main.as:
[SWF(width="465", height="465", backgroundColor="0x000000", frameRate="30")]
O links para donwload:Triângulo de Pascal

domingo, 5 de julho de 2009

Clonando objetos em PHP

Estes dias eu estava escrevendo um código que parecia mais ou menos assim (está simplificado aqui):


$instancia_robo = new Robo();
$robos = array();
for($i = 0; $i < 5; $i++) {
$robo = $instancia_robo;
$robo->id = $i;
$robos[] = $robo;
}
var_dump($robos);


Eu achava que não tinha necessidade de ficar instanciando a variável $robo dentro do loop para poder ter diferentes instancias dela (e isso teria funcionado no php versão 4, alguém ainda usa esta versão?). No php 5 agora todos os objetos são passados por referência (coisa feia eu não saber disso, eu sei). Mas esta versão do php providencia uma palavra chave chamada clone. Exemplo abaixo:


echo 'Usando clone';
$instancia_robo = new Robo();
$robos = array();
for($i = 0; $i < 5; $i++) {
$robo = clone $instancia_robo;
$robo->id = $i;
$robos[] = $robo;
}
var_dump($robos);


Compare os dois códigos rodando para você ver a diferença. Os objetos dentro do array no código usando clone ficam com a sequência correta. Uma forma de arrumar o primeiro código sem usar o clone seria instanciando a variável $robo dentro do loop ao invés dela receber a variável $instancia_robo. Os próximos códigos tentam fazer um comparativo do tempo que cada comando leva (um usando clone e outro instanciando a variável dentro do loop).
Clone:

ini_set("memory_limit","512M");

class Robo {

public $id;
}

define('MAX_NUMEROS', 1000000);

echo 'Usando clone', '
';
$instancia_robo = new Robo();
$robos = array();
$start= microtime(TRUE);
for($i = 0; $i < MAX_NUMEROS; $i++) {
$robo = clone $instancia_robo;
$robo->id = $i;
$robos[] = $robo;
}
$finish = microtime(TRUE);
echo 'Tempo decorrido ', $finish - $start;


Instância:

ini_set("memory_limit","512M");

class Robo {

public $id;
}

define('MAX_NUMEROS', 1000000);

echo 'Instanciando', '
';
$robos = array();
$start = microtime(TRUE);
for($i = 0; $i < MAX_NUMEROS; $i++) {
$robo = new Robo;
$robo->id = $i;
$robos[] = $robo;
}
$finish = microtime(TRUE);
echo 'Tempo decorrido ', $finish - $start, '
';


Rodando no meu computador (Dual core 1.73 GHZ, 2 GB RAM) as diferenças de tempo de execução dos dois códigos foram pequenas.
Comparando:
Clone
1 - 3,01864814758
2 - 3,74507808685
3 - 2,97225308418
Média: 3,24532644
Instância
1 - 3,50589299202
2 - 4,54684591293
3 - 3,42544102669
Média: 3,826059977
É claro que o teste não tem muito rigor. Provavelmente os resultados dependem mais da complexidade da classe do objeto. Se tivéssemos usado uma classe com métodos mágicos como __construct provavelmente as diferenças seriam maiores a favor do comando clone.