BaseTrn vs Defined by en For each

Tiempo atrás, cuando queremos forzar que un for each leyera una tabla especifica, debíamos poner en la sentencia for each un Defined by de la forma

for each
   defined by <AtributoSecundario> //Está solo en la tabla que quiero recorrer.
..
endfor


Esto solo era necesario en algunas tablas, pero tiene varias consecuencias adversas, como que el atributo secundario figura como usado, que se agrega en la sentencia aunque no sea necesario, que si quiero borrarlo debo cambiar varios programas, etc.

Creo que fue en la versión Evo3, se agregó la posibilidad de especificar la Tabla Base del for each, poniendo una lista de transacciones y en forma indirecta se especifica cual tabla debo recorrer.

Para esto, la sintaxis es parecido a:

for each <Transaccion.Nivel> //Nivel de transaccion que define la tabla que quiero recorrer
  ...
endfor


Esta sintaxis tiene como contra que el objeto transacción queda referenciado y parece que lo estuviera llamando con un CALL lo cual no es cierto. Esto es un problema cuando se trata de analizar codigo con KBDoctor y demas, pero no produce gran lio para el desarrollador en el IDE.

Tiene la ventaja que queda mucho mas claro la intención del código, al leerlo con la transacción base que con el defined by.

Ademas, quise revisar si era mas rápido especificar con defined by que con BaseTrn, para eso hice un procedure bien sencillo.

//Con Defined by
For each 
defined by ACEP_DIF 
     &Codi_aduan  = CODI_ADUAN 

Endfor

vs
//Con Transaccion base
For each POLIZAI
     &Codi_aduan  = CODI_ADUAN 
Endfor

y tomé los tiempos del View Navigation en una KB grande.


View Navigation For each
   Defined by
   For each
    BaseTrn
1
   11.67
      8.51
2
    5.75
  4.74
3
    4.84
4.09
4
   10.97
8.58
Promedio
    8.30
6.48

Si bien hay que comprobarlo con otros for each mas complicados y otras KB, en este sencillo experimento, vemos que es un 20% mas rapido y queda mas claro, por lo que es recomendable sustituir los for each por la transacción base.

Seria bueno tener una herramienta que permita sustituir todas las ocurrencias del Defined by por la transacción que las contiene como atributos secundarios, para hacer una prueba a gran escala.

Si alguien quiere hacer mas rapido su proceso de build all, estaria buenisimo si puede hacer el siguiente experimento en una KB que tenga defined by:

1) Rebuild all y tomar tiempo con /MeasureCommandTime
2) Sustituir todos los defined by por la Transacción Base.
3) Rebuild all y tomar tiempo
4) Comparar resultados y hacerlos públicos (puede ser en los comentarios de este post o mejor en el Wiki).

UPDATE:  Hice la prueba, en una KB de 1702 objetos.
Tenia 25 defined by.
Los cambio a BaseTrn.

El tiempo de un Rebuild all, paso de 18.18 minutos (1098 segundos) a 17.42 ( 1062 segundos).  Los tiempos bajaron un 4% aproximadamente. 
Tengo la sensación que en una KB mas compleja, los tiempos pueden mejorar un poco mas.





Ver también:
Comentarios sobre Defined by 
Multiple Base Transactions in a For Each command

Comentarios

  1. Buen apote.
    En general, lo "automatizable" a arrasado a lo "optimizable"... la pregunta es, puede ser "automáticamente óptimo" ?

    ResponderBorrar
  2. Cuando vos le pones cual es la transaccion base, estas ayudando a Genexus restringiendo muchisimo donde buscar, por lo cual lo hace un poco mas rapido.
    Si el tiempo de build all no es un factor de peso o cuello de botella en tu desarrollo, esta bien hacerlo de cualquiera de las dos formas.
    Ahora, si lo que quieres es optimizar el tiempo de build all, podes cambiar un poco tu codigo para hacer un poquito mas rapido tu proceso.

    Creo que es posible hacer un programa que tome todos los for each que tengan "defined by" y los cambien poniendo la transaccion base por la cual debe guiarse. No es trivial, pero puede hacerse y confio que va a funcionar en un porcentaje alto de for each.

    Cuando tenga un tiempo, voy a incorporarlo al KBDoctor.
    Creo que haciendo antes y despues del cambio una comparacion de navegaciones, es un cambio de bajo riesgo y puede traer algunas ventajas interesantes.

    ResponderBorrar

Publicar un comentario

1) Lee el post
2) Poné tu opinión sobre el mismo.
Todos los comentarios serán leidos y la mayoría son publicados.

Entradas más populares de este blog

Aplicación monolítica o distribuida?

La nefasta influencia del golero de Cacho Bochinche en el fútbol uruguayo

Funcionalidades de GeneXus que vale la pena conocer: DATE Constants.