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.
Showing posts with label Tips en RPG. Show all posts
Showing posts with label Tips en RPG. Show all posts

Monday, May 23, 2022

Mejores Prácticas para mejorar el performance -I-

                            


En este oportunidad, tres sencillos tips para mejorar el performance del programa Rpg

 

 

 

 

1.-Subrutinas versus Subprocedures.


El uso de Subprocedure ofrece las siguiente facilidades:

  • Uso de variables locales
  • Pase de parámetros
  • Puede ejecutarse como funciones (Built-in)
  • Puede ser exportado a otros programas.

Si no es necesario utilizar las facilidades que brinda el uso de subprocedures es preferible utlizar subrutinas. 

En general el EXSR se ejecuta más rapidamente que la invocación a un subprocedure.

 

 2.-El uso de SETLL en lugar de CHAIN.

  SETTL y %Equal responde más rapidamente que CHAIN.

Si solamente se  requiere determinar si un registro con cierta clave existe o no existe, es preferible utilizar el settl.

Algunos autores esgrimen que la diferencia es insignificante, sin embargo cuando se trabaja con millones o billones de registros puede ser significativo ahorrar tiempo tanto como sea posible.


3.-Registros Retenidos (Allocated)

Aunque este punto no es una mejora del performance de por sí, es conveniente prestar atención a esto para evitar fallas y retrasos a tiempo de ejecución.

Supongamos que tenemos un archivo declarado update y realizamos la siguiente operación:

        chain (clave1: clave2)  archivo;

        If campo1 = 'Y';

          campo2 = '001';

          update archivo;

       Endif;

 Esta secuencia de instrucciones aparentemente inofensivas puede dejar "allocated" un registro si la condición CAMPO1 = 'Y' no se cumple ya que no hay un ELSE que libere (unlock) el registro retenido con el chain.

      

 

        

     Si te pareció interesante, reenvíalo a un amigo haciendo click en el sobrecito que está al final del artículo o en el enlace de Linkedin que está encima de este mensaje.  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


Friday, July 26, 2013

¿Para qué sirven las variables tipo apuntador (pointer)?




En cualquier lenguaje de programación, un apuntador es una variable cuyo contenido es la dirección en memoria de otra variable, una estructura de datos o un procedimiento.

En RPG IV (o Free) el tipo de variable APUNTADOR se especifica en la hoja D colocando este carácter en la posición correspondiente a la definición del tipo:   *
Esto le indica al compilador que la variable se utilizará para guardar la dirección en memoria de alguna otra estructura de datos. El contenido de esta variable tipo apuntador no se modifica a lo largo del programa. En cambio, para una variable de otro tipo (numérica, alfabética, estructura de datos, arreglos, etc.)  el programador puede modificar su valor.

Una variable tipo apuntador puede contener la dirección de un procedure o de una variable. Si el apuntador contiene la dirección de un procedure, debe utilizarse la palabra clave (Keyword) PROCPTR en la definición del apuntador.

Un apuntador que es utilizado para contener la dirección de variables o estructuras de datos es denominado “puntero de base” en inglés (basing pointer). Se puede acceder a variables, estructuras de datos y arreglos mediantes estos  punteros de base. La palabra clave (Keyword) BASED  es especificada en la definición de la variable cuyo valor es asignado según el contenido de una dirección de otra variable.

Un ejemplo de este código es el siguiente:
d  W_Pointer     s               *
d   w_nombre   s             30   inz(‘Maria Jimenez’)                  
d  Nombre         s             05    based(W_Pointer) 
W_pointer = %addr(W_nombre)

En este punto la variable Nombre tiene el contenido  ‘Maria’
Cabe destacar que mientras la variable W_pointer no tenga dirección asignada no se puede trabajar con la variable Nombre. Solo a partir del momento en que se asigna a la variable w_pointer una dirección de memoria con la operación %addr puede trabajarse con el contenido de la variable Nombre. Esto es así, porque la variables BASED no tienen memoria asignada hasta que el programa no esté cargado en memoria.
La variable Nombre hace referencia, en su definición a la variable tipo apuntador W_Pointer que va a contener la dirección en memoria de la variable que realmente contiene la data.

Muchos dirán: muy interesante el tema pero,  ¿Para qué sirve el uso de Apuntadores?

Las estructuras de datos y las variables que han sido declaradas BASED (la variable Nombre del ejemplo) pueden utilizar almacenamiento dinámico.

Con almacenamiento dinámico, la cantidad de memoria asignada al programa puede variar. Tradicionalmente cuando declaramos una matriz o arreglo (Array) con un numero incierto  de elementos. Declaramos el arreglo  con el máximo número de elementos que pensamos que pueden generarse a tiempo de ejecución, aun cuando raramente eso pueda suceder. Se desperdicia memoria y puede degradarse el rendimiento del equipo. Con el uso de apuntadores la historia cambia.

La función %Alloc asigna un numero de bytes en memoria a un apuntador.
En este ejemplo. Se declara un arreglo de 1000 posiciones. 
Sin embargo se asignan en memoria las primeras 100

d  W_Pointer     s               *
d   w_array        s             10     dim(1000) based(w_pointer)    
             
                 W_pointer = %Alloc(100)
                             W_pointer = %addr(W_array)


Memoria adicional puede ser asignada utilizando la función: %Realloc

                             w_pointer= %realloc(w_pointer:200)

Ahora se puede trabajar con 200 elementos del arreglo.

Parámetros tipo apuntador y apuntadores a procedures son muy utilizados en las Apis. Este uso y otros múltiples usos de los apuntadores los estaremos comentando en   próximos artículos.


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