BlackTDN Search

sábado, 28 de agosto de 2010

Protheus :: Dica de Otimização de Código ADVPL

Nesses meus anos como desenvolvedor Advpl tenho me deparado com absurdos de códigos como o fragmento do modelo abaixo:


1:   dbSelectArea("SRA")
 2:   dbSetOrder(1)
 3:   dbGoTop()
 4:   While !Eof() .and. xFilial("SRA") == RA_FILIAL
 5:  cSRAMat := RA_MAT
 6:  dbSelectArea("SRB")
 7:  dbSetOrder(1)
 8:  dbGoTop()
 9:  dbSeek(xFilial("SRB")+cSRAMat)
10:  IF !Found()
11:   dbSelectArea("SRA")
12:   dbSkip()
13:   Loop
14:  EndIF
15:  While !Eof() .and. xFilial("SRB") == RB_FILIAL .AND. RB_MAT == cSRAMat
16:   //Pega os Dependentes
17:   dbSelectArea("SRB")
18:   dbSkip()
19:  End While
20:  dbSelectArea("SRA")
21:  dbSkip()
22:   End While
      

Que se reescrito, pensando em reduzir a quantidade de linhas do programa e visando, principalmente, a otimização do processo, teríamos algo como:


1:  SRA->( dbSetOrder(1) )
 2:  SRA->( dbGoTop() )
 3:  cSRAFilial := xFilial( "SRA" )
 4:  SRB->( dbSetOrder( 1 ) )
 5:  While SRA->( !Eof() .and. cSRAFilial == RA_FILIAL )
 6:  IF SRB->( dbSeek(SRA->( RA_FILIAL+RA_MAT ) ) )
 7:   While SRB->( !Eof() .and. RB_FILIAL+RB_MAT == SRA->(RA_FILIAL+RA_MAT) )
 8:    //Pega os Dependentes
 9:    SRB->( dbSkip() )
10:   End While
11:  EndIF
12:  SRA->( dbSkip() )
13:  End While
      

Sem considerações....


"Tô Certo!"

[]s
иαldσ dj

...

3 comentários:

  1. Eai Naldo blz,

    (Isso não é uma critica, sem te conhecer tenho um respeito e admiração por você. Por correr atrás e disponibilizar tempo para atender a todos.) Porém...

    ...tenho visto você atendendo a pedidos das pessoas.
    Seu blog pode acabar virando um site cheio de dicas mas como um forum, e isso nao seria bacana.

    Faça o seguinte, quando alguém lhe perguntar,
    ?como faço?, ?deu erro?, ?me ensina?

    Pegue o problema dele e explique a raiz, faça-o entender explique como as coisas acontecem e assim consequentemente ele ira aprender.

    Sei de sua vontade de ajudar,
    e admiro. Espero um dia poder contribuir para
    o conhecimento de outros também.

    Abs,
    mais um Anônimo!

    ResponderExcluir
  2. Os exemplos são a base para o conhecimento. A partir deles, os interessados em aprender, irão se aprofundar e, na dúvida, buscarão novos exemplos tornando o aprendizado uma constante.

    Meus exemplos são quase que completos (complexos às vezes), mas têm um fim. Fazer pensar, incitar ao aprendizado e divulgar o conhecimento além de elucidar o desconhecido e perpetuar o saber.

    "Tô Certo!"


    []s
    иαldσ dj

    ResponderExcluir
  3. Opa, eai pessoal.

    (иαldσ dj, peço licença para completar seu post)
    Uma dica para update do post!

    Muitas pessoas (inclusive eu já fiz muito) fazem
    um laço ::FOR:: percorrendo posições do array da
    seguinte forma.

    Ex:

    For n := 1 To Len(aArrayExemplo)

    /*
    ...Instruções
    */

    Next n

    Mas como foi mostrado no exemplo acima para o
    laço ::WHILE::, a comparação que define a condição de parada
    do laço, irá ocorrer para cada volta ou 'loop',
    pois a condição será testada, neste exemplo a função ::Len(aArray)::
    E nessa comparação a função ::LEN:: será executada
    proporcionalmente ao tamanho do array usado.

    Portanto, a forma que produz melhor performance é;

    //Declare uma variável para controle dos laços e atribua a ela o valor retornado da função ::LEN::
    nArraySize := Len(aArrayExemplo)
    //Em seguida o ::FOR::
    For n := 1 To nArraySize

    /*
    ...Instruções
    */

    Next n

    Assim como foi explanado pelo иαldσ dj, as mesmas otimizações para um laço, são equivalentes para o ::WHILE:: e para o ::FOR::.


    []'s
    Sérgio

    ResponderExcluir