terça-feira, 30 de abril de 2013
Estimando o valor de pi usando um quadrado, um círculo e probabilidade
Existe uma técnica bem legal de se estimar o valor da constante π usando o quadrado e círculo abaixo:
O valor do raio do círculo é 1. Assim a área do círculo é π * r ^ 2 = π * (1 * 1) = π.
E a área do quadrado é :2 ^ 2 = 2 * 2 = 4. Só lembrando que estou usando o símbolo ^ para representar a exponenciação.
E agora nós selecionamos milhares de pontos dentro do quadrado. Para uma boa aproximação devemos fazer isso milhões de vezes. Uma vez isso feito você pode usar a seguinte fórmula para encontrar o valor de π:
π/4 = número de pontos dentro do círculo / número total de pontos
modificando a fórmula para encontrar o valor de π:
π = (número de pontos dentro do círculo * 4) / número total de pontos
Considerando-se que para obtermos um bom resultado devemos escolher milhões de pontos, seria muito demorado e entediante fazer este processo manualmente, portanto, nada melhor do que usarmos um computador para isso. E o programa em PHP abaixo faz exatamente isso:
Acredito que não seja difícil entender o código. Neste exemplo selecionamos 5 milhões de pontos dentro do quadrado. A inspiração veio deste link, lá você também pode encontrar uma boa explicação de como a técnica funciona. Ou você pode usar a constante M_PI da linguagem PHP.
quarta-feira, 6 de março de 2013
Eficiência Matemática
Vou mostrar-lhes dois trechos de código que fazem exatamente a mesma coisa:
Analisem os trechos de código e tentem descobrir o que eles fazem. Uma dica: a essência de tudo está na função calc.
Já analisou? Entendeu o que está acontecendo? Bom, estes trechos de código calculam 1 milhão de vezes a soma do intervalo de números entre 1 e um número aleatório entre 1 e 500. Ao mesmo tempo ele toma nota de quanto tempo este processo leva usando a função microtime.
Você conseguiu descobrir o que estava acontecendo antes de eu ter explicado? Se você não conseguiu, não tem problema, eu vou explicar. Comparando os dois trechos de código, qual você diria que apresenta com mais clareza o comportamento que expliquei anteriormente?
O primeiro trecho usa funções cujos nomes dão uma certa ideia sobre o que está acontecendo. "array_sum" retorna a soma dos valores dentro de um array. "range" retorna um array preenchido com números em um intervalo que vai do primeiro parâmetro passado até o segundo parâmetro passado. Então array_sum soma o conteúdo de um array, range retorna um array de números, bingo! Tudo o que o loop faz é somar os números naturais de 1 até um intervalo superior que varia de 1 até 500. Um milhão de vezes!
E o segundo trecho? Não há chamadas de funções nesta versão da função calc. Ela mais parece uma fórmula matemática. E realmente é, é a seguinte fórmula:
E ela simplesmente retorna a soma entre os números naturais de 1 até n.
Certo! O que eu quero demonstrar com tudo isso? Primeiro eu convido vocês a executar os trechos de código em seus computadores e comparar o tempo gasto nos cálculos tanto pelo trecho usando array_sum quanto pelo outro usando a fórmula matemática, no meu computador um core i7 2600 3,40 GHz os tempos em segundos, cada trecho foi executado três vezes, foram os seguintes:
array_sum:
Analisem os trechos de código e tentem descobrir o que eles fazem. Uma dica: a essência de tudo está na função calc.
Já analisou? Entendeu o que está acontecendo? Bom, estes trechos de código calculam 1 milhão de vezes a soma do intervalo de números entre 1 e um número aleatório entre 1 e 500. Ao mesmo tempo ele toma nota de quanto tempo este processo leva usando a função microtime.
Você conseguiu descobrir o que estava acontecendo antes de eu ter explicado? Se você não conseguiu, não tem problema, eu vou explicar. Comparando os dois trechos de código, qual você diria que apresenta com mais clareza o comportamento que expliquei anteriormente?
O primeiro trecho usa funções cujos nomes dão uma certa ideia sobre o que está acontecendo. "array_sum" retorna a soma dos valores dentro de um array. "range" retorna um array preenchido com números em um intervalo que vai do primeiro parâmetro passado até o segundo parâmetro passado. Então array_sum soma o conteúdo de um array, range retorna um array de números, bingo! Tudo o que o loop faz é somar os números naturais de 1 até um intervalo superior que varia de 1 até 500. Um milhão de vezes!
E o segundo trecho? Não há chamadas de funções nesta versão da função calc. Ela mais parece uma fórmula matemática. E realmente é, é a seguinte fórmula:
E ela simplesmente retorna a soma entre os números naturais de 1 até n.
Certo! O que eu quero demonstrar com tudo isso? Primeiro eu convido vocês a executar os trechos de código em seus computadores e comparar o tempo gasto nos cálculos tanto pelo trecho usando array_sum quanto pelo outro usando a fórmula matemática, no meu computador um core i7 2600 3,40 GHz os tempos em segundos, cada trecho foi executado três vezes, foram os seguintes:
array_sum:
- 42,979010105133
- 42,527684926987
- 43,008407831192
- 9,8508331775665
- 9,889456987381
- 9,9301979541779
Eu acredito que a grande diferença de eficiência de execução se deve principalmente a dois pontos principais. A função range cria um array dinamicamente e isso envolve alocação de memória por parte do interpretador PHP, o que toma tempo. Mas é o segundo ponto que deve realmente impactar na performance, a função array_sum deve percorrer cada elemento do array gerado pela função range e laços de repetição afetam a performance significativamente.
Eu não tenho dúvidas de que o código usando array_sum é mais fácil de se ler, mais elegante e usa todo o poder do dinamismo da linguagem PHP. Mas a eficiência da abordagem matemática é inegável, e alguns até poderiam dizer que ela é tão elegante quanto a outra, sempre podemos adicionar um comentário informando o que a fórmula faz, não é? Acho que preciso voltar a estudar matemática.
terça-feira, 19 de fevereiro de 2013
Como testar o desempenho de suas aplicações web de forma fácil e rápida
Você acabou de finalizar os últimos retoques no seu site ou aplicação. O cliente já fez exaustivos testes além dos testes realizados por você mesmo. Tudo pronto para colocar em produção aquele código no qual você passou meses trabalhando. E de repente, quando mais de 30 usuários estão fazendo requisições ao mesmo tempo, as requisições demoram a serem respondidas. Parece que a página inicial do site não vai aparecer nunca. Clicar em "salvar" naque formulário de cadastro se torna uma bela desculpa para uma pausa para café.
"Mas como isso está acontecendo?" Você se pergunta. Nos testes realizados as resquisições demoravam poucas dezenas de milisegundos. Como isso foi acontecer? Bom, provavelmente os testes foram realizados com apenas um usuário acessando o servidor, talvez dois. Com o site ou aplicação se tornando popular vários usuários vão fazer seu código ser executado em várias requisições ao mesmo tempo. E é neste momento que estas supresas aparecem.
Para te ajudar a tentar prever como seu código vai se comportar com várias requisições simultâneas existe uma ferramenta muito útil chamada ab (Apache Benchmark), sobre a qual já falei aqui. Em uma máquina com gerenciador de pacotes como o apt-get instalá-la é muito fácil. Basta usar o comando:
#apt-get install apache2-utils
Sua execução básica é assim:
$ab -c 10 -t 30 http://localhost/sitecobaia/
Este comando vai abrir 10 conexões simultâneas e enviar requisições durante 30 segundos para o endereço indicado. Uma variação deste comando é adicionar um parâmetro para que as conexões sejam do tipo keep-alive(comum nas as requisições enviadas por navegadores).
$ab -kc 10 -t 30 http://localhost/sitecobaia/
Quanto aos números você é livre para alterá-los como quiser. Se você for realmente sádico coloque algo como 100 requisições simultâneas durante 60 segundos e veja seu servidor sofrer.
Um exemplo de saída ao comando ab pode ser visto abaixo:
This is ApacheBench, Version 2.3 <$Revision: 655654 $>
Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
Licensed to The Apache Software Foundation, http://www.apache.org/
Benchmarking localhost (be patient)
Finished 484 requests
Server Software: Apache/2.2.20
Server Hostname: localhost
Server Port: 80
Document Path: /sitecobaia/
Document Length: 43666 bytes
Concurrency Level: 10
Time taken for tests: 30.022 seconds
Complete requests: 484
Failed requests: 0
Write errors: 0
Keep-Alive requests: 0
Total transferred: 21502202 bytes
HTML transferred: 21134344 bytes
Requests per second: 16.12 [#/sec] (mean)
Time per request: 620.291 [ms] (mean)
Time per request: 62.029 [ms] (mean, across all concurrent requests)
Transfer rate: 699.43 [Kbytes/sec] received
Connection Times (ms)
min mean[+/-sd] median max
Connect: 0 0 0.2 0 2
Processing: 349 614 108.0 608 950
Waiting: 344 598 105.6 591 932
Total: 349 614 108.0 608 950
Percentage of the requests served within a certain time (ms)
50% 608
66% 658
75% 688
80% 707
90% 750
95% 798
98% 845
99% 875
100% 950 (longest request)
Alguns números mostrados são interessantes. Como por exemplo a média de requisições por segundo(Requests per second) que neste caso foi de 16,12. Quanto mais alto este número mais requisições seu servidor servirá em menos tempo. A média de tempo(Time per request) por requisição também é interessante de ser observada. Neste caso temos dois valores, o primeiro, indica o tempo médio em milisegundos que o servidor demorou para responder uma única requisição, neste caso 620,291 ms. Ou seja com 10 conexões concorrentes a resposta demourou em média pouco mais de meio segundo para chegar(1 segundo tem 1000 milisegundos). O segundo valor da média de tempo por requisição é o resultado da divisão do tempo total para todas as requisições(30,22 segundos ou 30022 milisegundos) pelo número de requisições completas (484) o que dá o valor de 62,029 milisegundos por requisição.
No final temos um resumo da porcentagem de requsições respondidas dentro de um certo tempo em milisegundos. Observem que 50% das requisições demoraram no máximo 608 ms para serem respondidas. E a requisição mais demorada demorou 950 ms.
Um resultado que pode deixar-nos confusos quando usamos o ab com sites dinâmicos é o seguinte:
Failed requests: 32951
(Connect: 0, Receive: 0, Length: 32951, Exceptions: 0)
Você pensa: "Porque ele reportou que 32951 requisições falharam?". Mas observe que o tipo de erro foi de tamanho(Length), isso acontece porque o ab considera que quando os tamanhos das respostas diferem da primeira resposta obtida do servidor acontece um erro de Length. Como em páginas dinâmicas coisas como identificadores de sessão, cookies ou até mesmo o conteúdo da resposta podem mudar de uma requisição para outra este tipo de "erro" pode aparecer frequentemente.
"Mas como isso está acontecendo?" Você se pergunta. Nos testes realizados as resquisições demoravam poucas dezenas de milisegundos. Como isso foi acontecer? Bom, provavelmente os testes foram realizados com apenas um usuário acessando o servidor, talvez dois. Com o site ou aplicação se tornando popular vários usuários vão fazer seu código ser executado em várias requisições ao mesmo tempo. E é neste momento que estas supresas aparecem.
Para te ajudar a tentar prever como seu código vai se comportar com várias requisições simultâneas existe uma ferramenta muito útil chamada ab (Apache Benchmark), sobre a qual já falei aqui. Em uma máquina com gerenciador de pacotes como o apt-get instalá-la é muito fácil. Basta usar o comando:
#apt-get install apache2-utils
Sua execução básica é assim:
$ab -c 10 -t 30 http://localhost/sitecobaia/
Este comando vai abrir 10 conexões simultâneas e enviar requisições durante 30 segundos para o endereço indicado. Uma variação deste comando é adicionar um parâmetro para que as conexões sejam do tipo keep-alive(comum nas as requisições enviadas por navegadores).
$ab -kc 10 -t 30 http://localhost/sitecobaia/
Quanto aos números você é livre para alterá-los como quiser. Se você for realmente sádico coloque algo como 100 requisições simultâneas durante 60 segundos e veja seu servidor sofrer.
Um exemplo de saída ao comando ab pode ser visto abaixo:
This is ApacheBench, Version 2.3 <$Revision: 655654 $>
Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
Licensed to The Apache Software Foundation, http://www.apache.org/
Benchmarking localhost (be patient)
Finished 484 requests
Server Software: Apache/2.2.20
Server Hostname: localhost
Server Port: 80
Document Path: /sitecobaia/
Document Length: 43666 bytes
Concurrency Level: 10
Time taken for tests: 30.022 seconds
Complete requests: 484
Failed requests: 0
Write errors: 0
Keep-Alive requests: 0
Total transferred: 21502202 bytes
HTML transferred: 21134344 bytes
Requests per second: 16.12 [#/sec] (mean)
Time per request: 620.291 [ms] (mean)
Time per request: 62.029 [ms] (mean, across all concurrent requests)
Transfer rate: 699.43 [Kbytes/sec] received
Connection Times (ms)
min mean[+/-sd] median max
Connect: 0 0 0.2 0 2
Processing: 349 614 108.0 608 950
Waiting: 344 598 105.6 591 932
Total: 349 614 108.0 608 950
Percentage of the requests served within a certain time (ms)
50% 608
66% 658
75% 688
80% 707
90% 750
95% 798
98% 845
99% 875
100% 950 (longest request)
Alguns números mostrados são interessantes. Como por exemplo a média de requisições por segundo(Requests per second) que neste caso foi de 16,12. Quanto mais alto este número mais requisições seu servidor servirá em menos tempo. A média de tempo(Time per request) por requisição também é interessante de ser observada. Neste caso temos dois valores, o primeiro, indica o tempo médio em milisegundos que o servidor demorou para responder uma única requisição, neste caso 620,291 ms. Ou seja com 10 conexões concorrentes a resposta demourou em média pouco mais de meio segundo para chegar(1 segundo tem 1000 milisegundos). O segundo valor da média de tempo por requisição é o resultado da divisão do tempo total para todas as requisições(30,22 segundos ou 30022 milisegundos) pelo número de requisições completas (484) o que dá o valor de 62,029 milisegundos por requisição.
No final temos um resumo da porcentagem de requsições respondidas dentro de um certo tempo em milisegundos. Observem que 50% das requisições demoraram no máximo 608 ms para serem respondidas. E a requisição mais demorada demorou 950 ms.
Um resultado que pode deixar-nos confusos quando usamos o ab com sites dinâmicos é o seguinte:
Failed requests: 32951
(Connect: 0, Receive: 0, Length: 32951, Exceptions: 0)
Você pensa: "Porque ele reportou que 32951 requisições falharam?". Mas observe que o tipo de erro foi de tamanho(Length), isso acontece porque o ab considera que quando os tamanhos das respostas diferem da primeira resposta obtida do servidor acontece um erro de Length. Como em páginas dinâmicas coisas como identificadores de sessão, cookies ou até mesmo o conteúdo da resposta podem mudar de uma requisição para outra este tipo de "erro" pode aparecer frequentemente.
segunda-feira, 28 de janeiro de 2013
Código fonte de jogo flash opensource
Olá a todos.
Acabei de criar um repositório no github com o código fonte de um pequeno jogo que criei usando Action Script 3 e a biblioteca flixel. O nome do jogo é DarkMatters.
O jogo é bem simples e criei com a intenção de aprender mais sobre o processo de desenvolvimento de um jogo. Infelizmente o código não é de grande qualidade mas espero que possa ajudar alguém interessado no assunto.
Acabei de criar um repositório no github com o código fonte de um pequeno jogo que criei usando Action Script 3 e a biblioteca flixel. O nome do jogo é DarkMatters.
O jogo é bem simples e criei com a intenção de aprender mais sobre o processo de desenvolvimento de um jogo. Infelizmente o código não é de grande qualidade mas espero que possa ajudar alguém interessado no assunto.
terça-feira, 22 de janeiro de 2013
Livros grátis para aprender PHP
Aqui vai um link que pode ser de muita ajuda para quem está querendo aprender como programar em PHP.
http://www.linuxlinks.com/article/20130119004851789/9oftheBestFreePHPBooks-Part1.html
Neste link tem uma lista de 9 livros grátis sobre PHP. Aproveitem!
http://www.linuxlinks.com/article/20130119004851789/9oftheBestFreePHPBooks-Part1.html
Neste link tem uma lista de 9 livros grátis sobre PHP. Aproveitem!
terça-feira, 18 de dezembro de 2012
WEB Advent
Alguém aí já ouviu falar do PHP Advent (que aparentemente este ano mudou o nome para WEB Advent)?
Todo mês de dezembro, desde de 2007, várias pessoas são convidadas a escreverem artigos com dicas, conselhos, truques e o que mais estiver em suas mentes. Tem conteúdo sobre desenvolvimento de software, web, design, php etc. Os artigos são muito interessantes e são escritos por pessoas conhecidas na comunidade. Não perca mais tempo e acesse o WEB Adevent 2012. Lá tem links para os anos anteriores também.
Todo mês de dezembro, desde de 2007, várias pessoas são convidadas a escreverem artigos com dicas, conselhos, truques e o que mais estiver em suas mentes. Tem conteúdo sobre desenvolvimento de software, web, design, php etc. Os artigos são muito interessantes e são escritos por pessoas conhecidas na comunidade. Não perca mais tempo e acesse o WEB Adevent 2012. Lá tem links para os anos anteriores também.
segunda-feira, 26 de novembro de 2012
O Google cai e a internet cai!
Hoje 26/09/2012 na parte da tarde serviços da Google como busca, e-mail e o youtube apresentaram instabilidade quando se tentava acessá-los.
Notei duas coisas engraçadas no meu local de trabalho, primeiro foi uma garota que achou que a internet tinha "caído". O que até pode ser considerada uma reação normal quando muitas pessoas deixam a página inicial do browser apontada para o serviço de busca da Google (Se bem que neste particular caso de hoje os servidores da Google estavam retornando uma página de erro informando o status 502. Acho que ela é um pouco leiga na área).
Outra coisa que notei foi que muitas pessoas não conhecem ou não se interessam por outras ferramentas de busca. Durante os vários minutos em que o serviços de busca não estavam funcionando a maioria resolveu que era era o momento ideal para uma um lanche ou tomar um café. Serviços como bing ou yahoo não são lembrados.
Durante este sabático do serviço de busca da Google eu deve ter feito pelo menos umas 5 buscas, principalmente relacionadas a referência de funções PHP ou exemplos de código para alguma tarefa. Acontece que meu serviço de busca padrão é o pouco conhecido DuckDuckGo. Preocupações relacionadas ao efeito "bolha" me levaram a esta decisão.
Mas não pensem que sou algum radical que não usa mais a busca google. Na verdade ainda devo fazer mais buscas no google, no DuckDuckGo basta adicionar "!g" na frente dos termos de busca para que eu seja redirecionado para lá. Uso muitos serviços da Google que hospeda este blog, meu e-mail e muitos vídeos que assisto no youtube. Eu só tento evitar fazer buscas logado com minha conta Google, sempre tenho dois browsers abertos um com e-mail e Google Talk e outro para minhas buscas.
Notei duas coisas engraçadas no meu local de trabalho, primeiro foi uma garota que achou que a internet tinha "caído". O que até pode ser considerada uma reação normal quando muitas pessoas deixam a página inicial do browser apontada para o serviço de busca da Google (Se bem que neste particular caso de hoje os servidores da Google estavam retornando uma página de erro informando o status 502. Acho que ela é um pouco leiga na área).
Outra coisa que notei foi que muitas pessoas não conhecem ou não se interessam por outras ferramentas de busca. Durante os vários minutos em que o serviços de busca não estavam funcionando a maioria resolveu que era era o momento ideal para uma um lanche ou tomar um café. Serviços como bing ou yahoo não são lembrados.
Durante este sabático do serviço de busca da Google eu deve ter feito pelo menos umas 5 buscas, principalmente relacionadas a referência de funções PHP ou exemplos de código para alguma tarefa. Acontece que meu serviço de busca padrão é o pouco conhecido DuckDuckGo. Preocupações relacionadas ao efeito "bolha" me levaram a esta decisão.
Mas não pensem que sou algum radical que não usa mais a busca google. Na verdade ainda devo fazer mais buscas no google, no DuckDuckGo basta adicionar "!g" na frente dos termos de busca para que eu seja redirecionado para lá. Uso muitos serviços da Google que hospeda este blog, meu e-mail e muitos vídeos que assisto no youtube. Eu só tento evitar fazer buscas logado com minha conta Google, sempre tenho dois browsers abertos um com e-mail e Google Talk e outro para minhas buscas.
Assinar:
Postagens (Atom)

