Má experiência: Os cuidados ao se adotar parcialmente praticas ágeis.
Depois de um tempo digerindo uma situação que passei, estou postando, tentando ser o mais imparcial possível.
(Antes me desculpem pelo post um pouco longo, mas acho que vale a pena!)
Eu tenho nos últimos tempos estudado bastante sobre desenvolvimento ágil, especialmente falando sobre práticas de XP (posso me referir a essas práticas, tanto como práticas ageis, quanto práticas de XP neste texto), como pareamento, TDD, revisão de código, valores do XP como coragem, comunicação, propriedade coletiva de código , etc. Este desejo de estudar desenvolvimento ágil, foi devido a algum tempo, enquanto desenvolvia software, eu tinha diversas sensações ruins, como o medo. O medo apareceu diversas vezes, quando eu alterava uma coisa e tinha medo que quebrasse coisas que dependiam dela. Então o que fazemos neste caso, testamos tudo relacionado.
Aqui nasce um primeiro problema, se testamos manualmente, como todo ser humano estamos sujeitos a erros, imagine a seguinte situação bastante comum em todos os projetos: imagina que desenvolvemos uma funcionalidade, e para esta funcionalidade executamos, digamos, 15 combinações de testes na mão. Agora desenvolvemos uma nova funcionalidade que depende da anterior, mas ai precisamos fazer alguma alteração na primeira funcionalidade. Agora temos que garantir que a primeira e a segunda funcionalidade continuam tendo o comportamento que esperamos. 0K até aqui nenhuma novidade, mas garantir que a funcionalidade anterior continua funcionando, significa que temos que executar os 15 testes da antiga, e digamos que para a nova funcionalidade há mais 15 testes.
Agora são 30!
Essas dependencias entre partes do meu sistemas, sabemos que são naturais, testar é necessário, mas sabemos que testar 30 cenário é bem chato! Além do que podemos esquecer, e mesmo se estiver escrito, podemos sem querer pular um cenário, isso quando não acaba a paciência e testamos apenas alguns poucos cenários que PENSAMOS ser necessários, etc.
Definitivamente esse tipo de coisa me deixava frustrado ao escrever aplicações. Eu não queria passar a minha vida inteira fazendo coisas desse tipo. Mas definitivamente, eu gostava do que fazia, gostava de escrever código, e ver coisas irem para a produção.
Outra coisa que me incomodava bastante é que eu não sabia escrever código bonitos, eu simplesmente não conseguia escrever código sem grandes lógicas condicionais, métodos extremamente grandes, dificeis de ler, de dar manutenção. E aqui nasce mais medo, mais frustração.
E perante a isso tudo, fui atrás de respostas, eu queria saber o que eu poderia fazer para melhorar tudo isso. E depois de passar por vários livros, estudando técnicas e metodologias eu acabei me deparando com ágil.
As práticas de XP que citei no começo elas tentam lidar com esses medos, exemplo: quando faço TDD, a cada passo que vou para frente, tenho um feedback, esse feedback me mostra se estou fazendo certo ou errado, se eventualmente estiver errado, volto e adoto uma nova abordagem, mas sem que seja necessário percorrer um grande caminho até perceber que eu estava errado. Além disso, os testes me força bastante a ter um cuidado com design e tomar bastante cuidados com a Orientação a Objetos, especialmente os test first do TDD. E isso me fez estudar bastante orientação a objetos também, fazendo com que eu evoluísse muito meus códigos, e conhecimento sobre padrões de projeto.
Outro ponto do TDD é que se automatizo meus cenários, não vou precisar testa-los a mão, é só rodar os testes e garanto que não quebrei nada, me permitindo que eu possa refatorar e melhorar o design do código deixando-o sucindo e funcionando! Isso reduz drasticamente meu extress ao desenvolver aplicação. E me deixa muito mais feliz, por que meus códigos estão muito mais interessantes, e flexiveis, além do mais não estou executando centenas, ou atém milhares de cenários de teste na mão.
Perante estes fatos, a primeira coisa que adotei no meu dia a dia, foi TDD. Apenas destacando que a equipe não adotava praticas ageis, a equipe adotava scrum (framework ágil, mas que não preocupações com qualidade interna de código).
Então um dia desenvolvendo uma funcionalidade, percebi um pequeno bug em um componente, ao olhar para dentro deste componente, vi que seria chato fazer a correção deste pequeno bug, por que era um código cheio de lógica condicional. Então com o valor de coragem no coração, eu escrevi testes que tentavam garantir o funcionamento deste componente, depois da famosa barra verde, eu refatorei o código para utilizar polimorfismo, removendo assim as inumeras lógicas condicionais, e deixando o código mais fácil de ler e mais sucinto! Ai depois veio a correção do pequeno Bug.
Depois fiz um pequeno teste de aceitação e tudo funcionando! TUDO?
Bom, não foi bem assim, este componente era usado por diversas outras funcionalidades, e esta correção que eu fiz (prestem bem a atenção, não foi a refatoração que quebrou o código e sim a correção do pequeno bug), gerou um outro bug para as funcionalidades que usavam esse componente. Isto devido a entrada diferente que era dada para este componente nos outros pontos do código!
Resultado, bug em produção, estress, superior bravo!
Mas e ai qual foi o problema realmente, mexer no que estava funcionando para os outros casos, ou seja, mexer no que estava FUNCIONANDO é ruim então? Quem desenvolve aplicações a algum tempo, quase sempre já viu ou participou de situações que alguém queria reescrever o código, por que estava muito difícil evoluir, incluir novas funcionalidades ou corrigir bugs. Então mexer no que está funcionando não é algo ruim, ajuda a melhorar, a encontrar bugs (como foi o caso), mas isso tem que ser feito com cuidado evidentemente, tem que ter cobertura de testes, e não somente unitário, os erros que estouraram no caso foram em telas, teste de aceitação nessas telas teriam sido capazes de ver que o código estava quebrando.
Então aqui está o primeiro ponto, escrevam testes, escrevam testes para tudo, vocês vão gastar tempo quando começarem, só depois de automatizar, é só rodar, e você não gastar tempo com testes na mão, e garante que funcionalidades existentes continuam funcionando!
Um outro ponto é o seguinte, eu sozinho fiz essa alteração, e não percebi que aquela alteração poderia afetar outras coisas, agora para mim, é evidente que eu deveria ter testado outras coisas que dependiam deste componente, não só o meu caso. Mas naquele momento isso não era tão evidente para mim, será que se tivesse algum outro desenvolvedor, ao meu lado a chance de detectar isso não teria aumentado?
Nós estamos falando aqui de pareamento, o par aumentaria bastante essa possibilidade, de ter visto esta dependencia. E muito provavelmente teríamos pego esses problemas.
Para quem diz, que pareamento é muita perca de tempo, pense em grande parte do desenvolvedores que conhecemos, quanto tempo eles perdem tempo, olhando eventualmente o twitter, facebook, etc. Não estou falando que não pode fazer isso, estou falando apenas que fazemos muito menos se estivermos com alguém do lado, trabalhamos o dia inteiro, sinceramente, saindo no final do dia com a sensação de que trabalhamos muito, e produzimos bastante, isso me dá uma sensação de satisfação muito grande!
E agora, e se outros devs além do par, olhassem para o código para ver as alterações, se é possível evoluir algo, se ve algum problema? Isso é a revisão de código!
Revisão do código aumentaria mais ainda a possibilidade da detecção do problema! E pensem por um momento, um exemplo clássico é muito útil, quando um escritor escreve um livro, passa por diversas revisões, por que certamente pode escrever algo errado. Qual é a chance de escrevermos algo errado, em algo que não é tão trivial como o código de nossa aplicação? É muito grande!
Bom, eu pensei bastante, e fiquei bastante surpreso como as práticas ágeis de desenvolvimento poderiam ter capturado este problema antes de ir para a produção. A adoção apenas do TDD, me ajudou bastante, mas é evidente adoção parcial, requer certos cuidados, principalmente se a equipe não está muito disposta a adotar as diversas práticas. Mas não espere que as pessoas em volta entendam isso. Temos que evoluir independentes dos erros que possam acontecer, e estes erros nos ensinam bastante!
Dica preciosa de JodaTime em tempos de mudança de horário de verão
http://joda-time.sourceforge.net/
Aqui nesse post, estou colocando algo que eu passei com JodaTime, eu não vou me preocupar com detalhes basicos da API. Se você não viu ainda, brinque um pouco e volte aqui por que creio que vai lhe ser muito útil.
A história começa mais ou menos assim: Um belo dia, eu chego na empresa, e me falam que os testes unitários estavam quebrando (olha o valor dos benditos testes unitários). Mas o curioso é o seguinte, nenhuma classe envolvida nos testes unitários foram alteradas. #MEDO!!!
Os testes eram referentes uma consulta em alguns objetos, eu tenho uma consulta que fazia usando joda time, para não ficar preso aos dias no qual eu estava escrevendo, eu fiz o seguinte:
Testa entre 7 e 4 dias atrás, dessa forma, toda vez que meu teste rodava, será com as datas com referencia no dia atual, não a uma data fixa.
Olhando para o teste junto com outro analista (agradeço ao Felipe Pedrine – @felipepedrini), o teste quebrou bem no dia que irá mudar o horário de verão, e na hora 00
A exceção era o seguinte:
- Exception in thread “main” org.joda.time.IllegalFieldValueException: Value 0 for millisOfDay is not supported: Illegal instant due to time zone offset transition: 2011-10-16T00:00:00.000 (America/Sao_Paulo)
BOOM!
E agora, o que fazemos batman?
O trecho de código era bem parecido com o seguinte:
diaDaMudancaDeHorarioDeVerao.millisOfDay().withMinimumValue();
bom caros devs, vamos pensar um pouco, devido ao time zone, o joda time sabe que nesse dia tem mudança de horário de verão. E se agente pensar ainda mais, vamos perceber uma coisa bem bizarra, mas é fato:
- no dia em que há a mudança de horário deve verão, os relógios são adiantados de 00:00 Hs para 01:00 Hs. Então na verdade no dia do horário da mudança, o periodo entre 00:00 e 00:59:59.999 SIMPLESMENTE NÃO EXISTE!!!!!!!!!!!!!!!
Óóóóóóóó que triste! E por que esse periodo não existe, a Classe DateTime do JodaTime se recusa o deixar você colocar o horário do dia com millis Segundos do dia como zero, como o código mostrado fazia.
Bom, mas o que podemos fazer?
Claro, isso depende um pouco do caso, o primeiro ponto é que essa aplicação, fazia consultas que eu tinha que pegar da primeira hora do dia, até a última hora do dia. A alternativa para este caso é a seguinte, use o LocalDate da seguinte forma:
- diaDaMudancaDeHorarioDeVerao.toLocalDate().toDateTimeAtStartOfDay()
Quando você usa o LocalDate, e chama o método toDateTimeAtStartOfDay, ele já se preocupa com o time zone para você, e não tentar começar o dia a meia noite, e sim a uma hora da manhã. Além do fato de ser totalmente compativel com time zone de paises como eu vi algum que a mudança de horário começar a uma hora da manhã para as duas horas da manhã (não me pergunte o porque).
- Se o sistema está com preocupações como ser 24/7, e a sua data precisa de hora, é melhor usar o LocalDateTime.
Apenas para reforçar, o problema só foi percebido, antes de entrar na produção, por que havia testes. Então escrevam testes, eles são para te dizer se algo está certo ou errado, antes de gerar um stress maior.
Abraço
[Editado]
P.S.: Agradeço aqui os meu camarada salsa @dcmdeivid que sempre faz revisões importantes nesses posts, Vlw velho!
Cobertura de Teste
Olá amigos, como estão?
Por coincidência, nos últimos dias eu participei de duas discussões sobre o quanto deveria ser a cobertura de código, principalmente quando falamos de TDD, imaginamos código com uma ótima cobertura. Mas que número representa essa ótima cobertura de teste.
Bom este assunto é sempre muito polemico e eu não poderia deixar de dar meus pitacos sobre este ele, também já muito discutido. Como sempre vou colocando que não sou o dono da razão então, eu me reservo o direito de escrever o que pensar, mas também me dou o direito de receber feedback, isso sempre é muito bem vindo!
Algumas das opniões mais comuns são as seguintes:
- Eu não testo algumas coisas por que não há tempo, o cliente chega uma hora e fala: esquece tudo isso ai por que eu quero virar minha versão semana que vem. No mundo corporativo isso não é possivel;
- A cobertura de teste tem que ser 100%, por que assim temos muita segurança na redução de bugs, mesmo que signifique em algum momento escrevermos testes mais intrusivos, e não ter 100% nos leva ao problema da janela quebrada, com certeza vai chegar um outro desemvolvedor que não vai escrever teste por que diz: há aquilo ali não está testado;
- Os testes serão escritos até o momento que eu tiver segurança de que aquilo que eu que eu quis implementar está DONE, isto é, eu codifiquei todo o comportamento que eu gostaria de codificar;
Bom me parece claro que usar TDD e ter uma boa cobertura de teste ajuda e muito as nossas aplicações a reduzirem drasticamente os bugs, economia de tempo em debug, nos tornamos muito mais confidentes do código que escrevemos, reduzimos drasticamente a programação por coincidência, reduzimos o tempo de manutenção, os testes são também ótima fonte de documentação, etc. Isto é os argumentos no primeiro questionamente são extremamente frageis. Ainda citando o fato da pessoa colocar: mas seu eu tenho uma camada do meu software que só faz delegação (bom creio que ele estava se referenciando aos antipattens Façade, e service usado como façade). Eu vou questionar o seguinte: para que eu preciso de camada de software que não faz nada só delega? (Estes problemas são os mesmo o por que tem um bando de gente usando remotabilidade, etc, a explicação é a seguinte: é por que ela nunca viu algo diferente e nunca se questionou se isso era realmente necessário).
Bom com isso considero esse argumento não valido.Partindo para o segundo argumento agora, mas eu vou descutir junto neste ponto a terceira opnião. Ter 100% de line coverage na nossa aplicação é realmente um ótimo cenário, temos um código totalmente testado, e isso de fato é muito bom. O problema é o seguinte, eu escrevo testes para cada pequeno comportamento que eu adiciono, fato, e chega um determinado momento que eu entendo como feito minha feature. Neste momento o que eu faço: rodo algo para gerar uma medida de cobertura de código para ver qual é a cobertura dessa nova feature, então eu faço o esforço necessário para que tenha a tão sonhada cobertura de 100%. Bom é neste momento que eu acho que as coisas começam a ficar um pouco esquisitas, este esforço tenta cobrir qualquer que seja a combinação possível do meu código, me dá a sensação de que deixou de ser qualidade da feature e sim a cobertura de código. Bom, é importante eu deixar claro aqui, que não estou falando que as coisas que eu faço de 0, 5, 10, 50, 90, 100% de line coverage, e nem estou dizendo que não devemos gerar medidas da cobertura de código dos nossos testes, até por que a medida pode nos dizer que um ponto da nossa aplicação está extremamente sujeito a falhas, por que os testes não cobrem adequadamente e devo atacar para dar qualidade a essa área. Eu estou defendendo que eu enquanto desenvolvendo não devo ficar preso ao 100%.
Kent Back enfatiza isso no TDD by example, e cita uma frase: Até que ponto eu testo? Até o ponto que a insegurança se torne monotonia. Além de dizer também, depois de um refactoring: Eu não escrevi um teste explicito para este caso, mas por que eu sei que se os testes que eu escrevi estiverem passando, então eu sei que o comportamento da minha classe está ok! Mas claro ele cita também a seguinte frase no final do capitulo 17, o TDD seguido religiosamente deveria gerar 100% de cobertura de teste. Batendo esta última afirmação com a penutima, podemos dizer o seguinte: Faça testes, use o baby step, isso certamente vai lhe aproximar da cobertura de 100%, por que a cada adição de um pequeno comportamento, você está gerando testes, e criando um armadura para a sua aplicação. Tire bastante medidas do seu código também, eles são ótimos para fazermos analises de problemas, mas também, não se desespere se rodar alguma tipo de medida e seu código tiver 90%, 95% ou 99% coberto, se você está seguro de o que você fez está funcionando, então os testes cumpriram sua obrigação enquanto garantia de qualidade do desenvolvido.
Lei de Demeter
Sempre que se fala em lei de demeter, causamos vários desconfortos!
http://en.wikipedia.org/wiki/Law_of_Demeter
Basicamente ele está falando daquela longa lista de encadeamento de chamadas de método, e que com razão ele fala que isto pode gerar acoplamento de uma unidade com diversas classes, já que quando fazemos essas chamadas, muitas vezes acabamos acessando mais de um objeto em uma unidade.
Sim, creio que isto sempre deve estar em nossas cabeças: ELE TEM COMPLETA RAZÃO! Mas e aquelas elegantes DSLs que utilizamos? Invariavelmente fazemos encadeamento de chamada de métodos, não é?
Bom, esquecendo a parte não fale com estranhos – que creio é um grande consenso – outros objetos diferente dos vizinhos – o caso é que ele descreve que não é bom cada unidade se relacionar com mais de uma unidade – sob uma perspectiva de comportamento em orientação a objetos, cada método deve ser uma unidade de comportamento.
Alguns defendem que o encadeamento de método é difícil para debugar. Esse argumento não é valido, já que como temos juízo desenvolvemos baseado em testes/comportamento cada unidade deve estar testada. 0k, argumento rejeitado!
Mas sinceramente, se, e somente se, a DSL se relacionar única e exclusivamente com o objeto e seu vizinho, continuamos respeitando de não falar com estranhos e entregamos ao usuário da API um grande conforto (a final, quem usa DSL sabe que a vida dos desenvolvedores é muito melhor!
).
Sinceramente, não há como abrir mão no nosso dia desta excelente ferramenta, muito útil, e que tornam nossas aplicações muito mais manuteniveis!
Martin Fowler chega a dizer que a lei de Demeter, na verdade deveria ser chamada de Sugestão de Demeter.
http://martinfowler.com/articles/mocksArentStubs.html
Bom, realmente acho que a Sugestão de Demeter é importantíssima, mas com certeza, pode ser adaptada as nossas necessidades, mas em fim, não ferimos tanto assim ela!
BDD não é um bixo que morde!
Olá amigos!
Tenho percebido que muitos desenvolvedores encaram a sigla BDD (Behavior Driven Development) como Outra coisa nova, para caras que nunca vão usar para nada.
Dan North desenvolveu esta abordagem, por que percebe que muitas das vezes os testes que ele desenvolvia ou em algum treinamento que ele aplicava era focado simplesmente em testar a aplicação, que efetivamente diversas vezes não tinha nenhuma relação com o negócio em si. Ou seja, o foco não estava no que o software deveria fazer, não estava no comportamento (Behavior), não estava no que realmente agrega valor ao cliente, na verdade estava em simplesmente testar a aplicação, criando coisas com grande cobertura de teste, mas que mesmo assim, diversas vezes falhavam em entregar as funcionalidades ao cliente.
http://dannorth.net/introducing-bdd/
A idéia então é focar no comportamento, para que seja desenvolvido o que realmente importa: o backlog. E a utilização de BDD não exclui o uso das tecnicas de TDD, muito pelo contrário. O único detalhe é o foco do desenvolvimento dos seus teste unitários ou de aceitação (ver link abaixo).
Bom quando disse acima que muitos dizem que é coisa nova, isto é algo que simplesmente mostra o esvaziamento das pessoas com relação a evolução de suas carreiras. Não estou falando nada de novo neste artigo (como sempre), gente muito mais respeitada do que eu já falou sobre este assunto, basta digitar no google, além do mais eu disse anteriormente que as técnicas de TDD devem ser utilizadas aqui, então efetivamente não há nada de novo.
O BDD está altamente enraizado hoje na comunidade Ruby, com os rock stars Test::Unit e RSpec/Cucumber, porém o primeiro framework para BDD que nasceu foi para java, o JBehavior. Então, não vejo o porque desta resistência! O JBehavior integra bem (obrigado!!!!) com o Maven, além de fazer excelente parceria com o selenium.
Abram espaço para o BDD, ele efetivamente pode ajudar nos seu projetos, e na sua carreira!
Abraços
Por que eu não uso mais component based!
No forum tectura, hoje colocaram uma pergunta interessante e antiga:
Request-Based ou Component-Based?
Bom, abaixo eu coloco um panorama do que aconteceu, mas basicamente eu trabalhei 3 anos com component based e trabalho a um pouco mais de 1 ano com action based, e minhas impressões são mostradas abaixo na resposta que eu postei.
Eu trabalhei por 3 anos com componente based, e gostava (creio que por falta de experiencia), achava que solucionava diversos problemas, como a não necessidade de conhecer html ou css tão a fundo toda aquela história pregada por estes frameworks, mas evidentemente eu passava por diversos problemas, por diversas vezes a manutenção me batia com component based. Exemplo, as validações que existem em jsf e ASP.net tem (hoje .net tem um framework MVC action based, tenho visto bons comentários sobre ele, mas não testei), quanto tempo passei debugando certas coisas, por que na verdade, vem uma pergunta: será que um código de validação deveria estar na view? Será que ele não deveria estar no controller? Componente based nos leva a misturar perigosamente as camadas do MVC. Eu comecei a procurar alternativas e me deparei com Spring MVC inicialmente, foi um CHOQUE, não tinha componentes! (Para falar a verdade tinha e eu sabia, mas queria testar ao que se propunha interamente o framework). E eu tive dificuldade (até por que tenho foco de backend), mas fui em frente, e quando me deparei havia solucionado diversos problemas que eu tinha, e não foi tão duro assim evoluir no html, css e js (até por que temos maravilhas como JQuery, ExtJs, etc).
O próximo passo foi o VRaptor 3, este foi o céu, consegui códigos extremamente testáveis (coisa muito dificil com JSF), expressivos, um mvc de ótimo nivel, aplicações extremamente manuteniveis, em fim, consegui utilizar muito bem orientação a objetos e TDD. De forma clara, meus métodos não recebem mais um actionEvent, agora eles recebem um formulario de cliente por exemplo, aonde aplico validações, e gero minha classe de modelo.
Além do que com EventBased temos mais vivo o conceito de recurso web, em geral os frameworks component based, utilizam de ações que ocorrem em eventos do tipo click em botão e assim por diante, e sabemos que isto destroi o rest, em jsf existem uma alternativa (RestFaces – http://bit.ly/kLK6xt), mas que me perdoem os que gostam de jsf, isto é puramente um hack.
Em fim, hoje estou extremamente tendencioso, e tenho experimentado exceletes resultados com actionBased, especialmente em primeiro lugar VRaptor 3 e em segundo Spring MVC.
Ahh, e não estou falando que não há sucesso com componente based (eu trabalhei em vários que deram certo). Estou falando que hoje eu tenho muito mais produtividade (gasto menos tempo e ganho mais dinheiro,
), e além do mais faço aplicações que depois de 1 ou 2 meses que vou mexer, eu não fico me xingando.
Um grande abraço!
Analisando padrão de Refactoring Split Loop
O padrão de refactoring Split Loop (http://www.refactoring.com/catalog/splitLoop.html), pode parecer absurdo para desenvolvedores que estão começando, devido ao aumento da constante de multiplicação para um número N de elementos.
Este padrão sugere ao desenvolvedor que se por exemplo, ele faz dois cálculos completamente distintos em um looping, este looping seja refatorando para dois loopings como descrito no link acima, isto vai melhorar a leitura do código, e consequentemente ganhar em manutenabilidade.
A confusão começa neste momento: Vou ganhar em manutenabilidade ou perder performance?
Apenas lembrando neste momento, algumas famosas frases sobre pensamento em desempenho precipitado:
“Mais pecados computacionais são cometidos em nome da eficiência (sem necessariamente alcançá-la) do que por qualquer outra razão – incluindo estupidez cega.“
- Willian A. Wulf
“Nós deveríamos esquecer as pequenas eficiências 97% das vezes: otimização prematura é a raiz de todo mal“
- Donald E. Knuth
“Nós seguimos duas regras a respeito de otimização:
Regra 1. Não faça
Regra 2 (apenas para experts). Não faça ainda – ou seja, não até que você tenha uma solução perfeitamente clara e não otimizada“
- M. A. Jackson
Uma operação que leva N passos passa a levar 2N (o que por sinal, segundo uma rápida analise assintótica, também é O(N)). Então há a tendência de dizer que isto degrada a performance do nosso código. Esta preocupação possivelmente tem origem em um tempo distante do desenvolvimento do software, aonde era necessário economizar cada bit utilizado, mas venhamos e covenhamos, atualmente dificilmente há situações como esta para o desenvolvimento de aplicações corporativas comuns. O que favorece a adoção maior de padrões para dar maior manutenabilidade e vivacidade as nossas soluções.
Então sugiro um pequeno programa, este programa vai fazer dois cálculos, somar um valor de 5000 e outro de 10000, N vezes (disponíveis em: OneLoop e TwoLoop), acompanhe a tabela.
|
N |
OneLoop (em milesegundos) |
TwoLoop (em milesegundos) |
|
100000000 |
971 |
819 |
|
1000000000 |
9570 |
8283 |
|
10000000000 |
95906 |
81502 |
TwoLoop aparece como mais rápido em todos os casos em minha máquina Intel ® Core ™ 2 Duo cada core com 2 GHz e 4 GB de memória, interessante também que quando faço com mais de dois loops (3, 4…), em comparação com 3,4… o split loop continua mais rápido.
Isto ocorre por que com dois loops o compilador faz uma série de otimizações. E no caso de serem dois arrays de mesmo tamanho em um loop há uma nova questão: a localidade da informação nas memórias próximas ao processador. Se o array A1 for levado para uma memória próxima ao processador (por exemplo, um dos níveis de cache) e depois solicitar uma posição em um array A2 no mesmo loop, há um boa possibilidade de haver miss de acesso a memória, forçando o processador a buscar esta informação na memória principal, o que também custa tempo.
A conclusão que se chega, é a mesma que muitos desenvolvedores (A maioria deles muito melhores que eu), já nos alertaram, não se preocupe demasiadamente com performance em termos de código. Preocupe-se muito mais com a clareza do seu código fonte, os seus amigos que forem dar manutenção agradecem.
Um grande Abraço!
|
N |
OneLoop (em milesegundos) |
TwoLoop (em milesegundos) |
|
100000000 |
971 |
819 |
|
1000000000 |
9570 |
8283 |
|
10000000000 |
95906 |
81502 |