Bienvenidos a Iseries Venezuela

Las mejores prácticas, recursos, tips, enlaces, videos y artículos para informáticos relacionados con el Iseries y el As/400 lenguajes de programación RPG, ILE RPG y SQL.

The best practices, resources, tips, links, videoes and articles for computer related to the Iseries and the As/400 languages of programming RPG, ILE RPG and SQL.

Saturday, April 26, 2014

Cinco Tips para Reducir el tiempo de Respuesta Mejorando el Código de programación en RPG

 











Optimizar un código de programación persigue dos objetivos:

Ø      Mejorar la legibilidad del código para reducir el tiempo que toma actualizarlo.

Ø      Reducir el tiempo de respuesta de la ejecución del programa

Cinco Tips para Reducir el tiempo de Respuesta Mejorando el Código de programación en RPG


1.-Uso de estructura de datos

En programación RPG II y RPG III, podemos ver, en general, una gran cantidad de MOVE, MOVEL para poder armar claves de búsqueda, grabar información en un archivo, realizar comparaciones de campos de longitud desigual, etc.

Declarar una estructura de datos con los campos o variables  y que tenga definidos los subcampos con sus diversas longitudes, nos permite hacer un solo MOVE y rellenar automáticamente todas las variables auxiliares que hemos utilizado durante el programa y que hemos repetidamente actualizado mediante MOVE y MOVEL.
Esto reduce sensiblemente el tiempo de respuesta del programa

2.-MOVE Versus Z-ADD

Consume menos tiempo de ejecución el MOVE que el Z-ADD
La instrucción Z-ADD implica internamente la realización de dos instrucciones: mover cero a la variable y luego sumarle un valor.
El MOVE directamente coloca el valor.

3.-SELECT Versus If Anidados

Algunas instalaciones tienen una verdadera fascinación por los IF anidados. Parece que mientras mas anidados y mas IF sean más eficiente es el programa: Todo lo contrario.
Utiliza SELECT en lugar de IF Anidados. El Select hace mas legible el programa y al evaluar la condición y verificar que se cumple, el sistema operativo abandona la evaluación del resto de las sentencias y pasa directamente a la siguiente instrucción por lo que el tiempo de respuesta se reduce considerablemente.





4.-Chain de Tablas Pequeñas

A veces tenemos un lazo por ejemplo un DO WHILE que lee un archivo de millones de registros. Por cada iteración se realiza un CHAIN a la tabla de sucursales por ejemplo. Si tenemos 6 millones de registros hacemos 6 millones de chain a una tabla que contiene 50 registros. Este acceso constante al disco para un archivo tan pequeño consume un tiempo enorme de ejecución.
Para reducir el tiempo de respuesta es preferible, al principio del programa, cargar la tabla de sucursales en un par de arreglos. Luego el lazo de los 6 millones de registros hace un Lookup a ese arreglo que fue cargado en memoria y leído solamente 50 veces.
Guao! muy distinto 50 accesos al disco que 5.999.950 ¿verdad?
Notaras la diferencia en tiempo de respuesta inmediatamente de manera impactante.



5.-Condiciones de los Lazos

Podemos realizar lazos de lecturas sobre un archivo DO WHILE  y dentro del lazo evaluar ciertas condiciones para determinar si abandonamos el lazo o permanecemos en el mismo. A veces se cumple la condición para salir del lazo y podemos aplicar un LEAVE en lugar de permanecer leyendo todo el archivo hasta fin de archivo.


Si quieres tener mayor información sobre este tema puedes revisar los artículos publicados por mi anteriormente en estos enlaces:






Si te pareció interesante, reenvíalo a un amigo haciendo click en el sobrecito que está al final del artículo. El conocimiento es valioso, compártelo. 




Autor: Ing. Liliana Suárez


Sunday, March 30, 2014

Algo más sobre Uso de Indicadores.

 







En un artículo anterior, al comenzar la edición de este blog, hice mención a varias recomendaciones a como usar los indicadores.


En esta oportunidad vamos a mencionar formas arcaicas o en desuso de los indicadores porque me lo han pedido en los últimos comentarios del blog.
Vamos a enfocarnos en:


Como NO utilizar los indicadores.

Hemos visto a programadores de RPG II y RPG III utilizar indicadores de esta forma:

N31N45N78       Move 1  VARIABLE

Algunas variaciones más monstruosas sobre el mismo tema.

N31N45N78    
Or
N78 78N90        Move 1  VARIABLE
     

Lo peor es que cuando incursionan en la programación con RPG IV conservan la misma forma arcaica de programar.

Luego de un tiempo el mismo programador no recuerda que diablos significa N31 N45  N78 y debe comenzar a realizar un análisis “forense” hasta dar con el concepto que involucra cada indicador.

Con RPG IV o con RPG FREE podemos declarar variables tipo Booleana en la hoja ‘D’ .Se declara tipo ‘n’ y listo!.

Por ejemplo si el indicador 31 indica que se aprobó el préstamo del cliente.
¿Por qué no declarar una variable tipo booleana? Una variable llamada: Prestamo_Aprobado.

Podemos hacer: Prestamo_Aprobado = *On  
Podemos hacer: Prestamo_Aprobado = *Off

Y luego preguntar:  If Prestamo_Aprobado 

¿Es más sencillo y claro de entender verdad?

Otro uso arcaico de los indicadores es en las preguntas IF.

If *in03 = ‘1’  no es necesario preguntar si vale ‘1’ con colocar:

If  *in03       Es suficiente.

Lo mismo sucede con el indicador con negación delante:

If  *in03 = ‘0’ se reemplaza por: If Not *in03

Sin embargo la mayoría de los programadores se mantienen con su forma de programar en:
If  *in03 = ‘1’   If  *in03 = ‘0’ formas que denotan falta de claridad del programador en el manejo de las sentencias lógicas.

Es  lo mismo preguntar por *OFF que por ‘0’ al igual que preguntar por *ON que por ‘1’.

Hay instrucciones como el CHAIN el COMP que originalmente utilizan indicadores. Con la nueva programación en RPG-FREE se pueden utilizar operaciones como por ejemplo:

    Chain (Key1:Key2) Archivo    03    (El indicador 03 es opcional)

If %Found(archivo)  equivale a preguntar If  not*in03

La operación COMP que ya NO se usa es reemplazada por una condición estándar de
Comparación:   IF A > B

Otra costumbre en la vieja programación es esta:

45                         A IFGT B
                                 …..
                  ENDIF
Esto significa que si el indicador 45 esta encendido (*ON) ejecutar el IF y todo lo que hay adentro.
Esta es otra práctica que dista de estar entre las mejores prácticas de programación en RPG. Utilice todas las condiciones que necesite en la sentencia IF para despejar cualquier duda de su ejecución.

En Rpg_Free ya no es necesario el uso de indicadores para buscar un elemento en un arreglo (Array)

Posicion= %Lookup(‘hola’: Array: 1:200)

En Posicion  se devuelve la posición del arreglo donde se encontró la palabra ‘HOLA’ si POSICION es cero entonces no está en el arreglo.
Un indicador menos que utilizar y podemos usar una variable mas mnemotécnica (Posicion)


Si puedes utilizar variables estándar o variables booleanas en lugar de indicadores, tendrás suficientes indicadores a tu disposición cuando requieras verdaderamente el uso de indicadores como es el caso del manejo de pantallas. Para ese caso, no hay manera de reemplazar indicadores de pantalla con variables booleanas. El SDA no da espacio para variables booleanas o nombres largos que permitan el manejo de campos y condiciones en Keywords de pantallas para el despliegue y actualización interactiva de datos.

El utilizar RPG-Free nos brinda muchas facilidades que nos permiten ser más claros, sencillos y directos en la programación.

Si quieres “migrar” a RPG-Free revalúa tus técnicas de programación para que no repitas los mismos vicios que aprendiste en códigos de programación mas atrasados.

 Para mayor información sobre este tema puedes consultar este enlace de otro artículo publicado por mí en este mismo blog, hace algún tiempo:



Si te pareció interesante, reenvíalo a un amigo haciendo click en el sobrecito que está al final del artículo. El conocimiento es valioso, compártelo. 



Autor: Ing. Liliana Suárez

Sunday, February 16, 2014

Precedencia En Operaciones. Parece Sencillo Pero Puede Ser Engañoso.


















En esta oportunidad vamos a repasar un tema que pareciera sencillo pero que puede dar a muchas complicaciones en los resultados finales de nuestros programas en RPG/RPGLE

Veamos el siguiente ejemplo en RPG III:


C   M02SRC     IFEQ   *BLANK
C   M02SRC     OREQ   'A'
C   $PGMDT     ANDGT  $RIFPG
C   $CMD       ANDEQ  'DREXTR'

¿Como interpretar esta operación?

Si no tenemos clara la prioridad que el sistema le asigna a cada operador
podemos suponer cualquiera de las siguientes interpretaciones como válida:

1.-(M02SRC = *Blanks) or ((M02SRC  = 'A') and $PGMDT > $RIFPG)
     and $CMD = 'DREXTR'

2.-(M02SRC = *Blanks or (M02SRC  = 'A')) and $PGMDT > $RIFPG))
     and $CMD = 'DREXTR'




La siguiente lista indica la prioridad en la evaluación de los operadores de una operación en RPG comenzando con el del mayor prioridad hasta el de menor prioridad.

  1. ()
  2. Built-in functions, user-defined functions
  3. unary +, unary -, NOT
  4. **
  5. *, /
  6. binary +, binary -
  7. =, <>, >, >=, <, <=
  8. AND
  9. OR
¿que significa esto?. 

Aplicándolo al ejemplo anterior:


C   M02SRC     IFEQ   *BLANK
C   M02SRC     OREQ   'A'
C   $PGMDT     ANDGT  $RIFPG
C   $CMD       ANDEQ  'DREXTR'


Supongamos que las variables tienen los siguientes valores:

M02SRC = 'H'
$PGMDT = 100
$RIFPG = 85
$CMD = 'DRINTR'

Primero se evalúan los operadores >,= (Mayor que e igual a)
 (En RPG III es equivalente a  GT, EQ, para el caso que nos concierne)

Estos dos operadores ocupan la posición 7 de la lista lo que significa que tienen mayor prioridad que los operadores AND y OR que ocupan la posición 8 y 9 respectivamente:

Evaluamos los = y el >

M02SRC = *Blanks     --> FALSO
M02SRC =  'A'             --> FALSO
$PGMDT > $RIFPG    --> VERDADERO
$CMD = 'DRINTR'     --> FALSO



Luego se evalúan los AND y posteriormente los OR, puesto que el AND está en un puesto 8 de mayor prioridad que el OR que ocupa el puesto 9 de la lista que presentamos anteriormente.

Entonces en un primer paso el sistema operativo evalúa las condiciones que he colocado entre paréntesis a la que les da prioridad por tener un operador lógico AND.

 (M02SRC  = 'A' and $PGMDT > $RIFPG) and ($CMD = 'DREXTR')
     
 (FALSO               and VERDADERO)           and (FALSO)

El resultado de los operadores AND es FALSO


el resultado de las operaciones AND =Falso se procede a evaluar contra el OR que es el operador restante:

M02SRC = *Blanks OR (FALSO)

(FALSO                     OR   FALSO) 

La condición es FALSA por lo que no procede la ejecución de los comandos que continúan dentro del IF

Esto equivale a transcribir la operación de la siguiente manera:

(M02SRC = *Blanks) or ((M02SRC  = 'A') and ($PGMDT > $RIFPG)
     and ($CMD = 'DREXTR'))


Se entiende que la evaluación de lo que está entre paréntesis tiene mayor prioridad por ocupar en puesto 1 de la lista, lo que equivale a evaluar las condiciones =, > en primer lugar y se continúa con el proceso anteriormente descrito.

La siguiente expresión es equivalente:

M02SRC = *Blanks or (M02SRC  = 'A' and $PGMDT > $RIFPG
     and $CMD = 'DREXTR')

Para conservar la lógica del programa original decimos al sistema operativo que queremos evaluar primero todo lo que está entre paréntesis que serían los AND y sus operadores de = y > asociados y el resultado de esto se evalúa contra el OR.

Es importante tener esto claro sobretodo cuando queremos transcribir programas en RPG III a programas RPG IV o A RPG-FREE de una manera mas legible para el programador.



Enlace de referencia:

Si te pareció interesante, reenvíalo a un amigo haciendo click en el sobrecito que está al final del artículo. El conocimiento es valioso, compártelo. 


Autor: Ing. Liliana Suárez