tnt400.com - AS/400 Tips And Techniques

Sponsored by news400.com

This page is a discussion on the mentioned topic.
Most of the answers are in their original posted form, including any technical/spelling/grammatical errors.
No guarantees are expressed or implied. :-)
Comments, corrections, concerns about this tip?

Got another AS/400 question? Ask it here


What's New?
See what's new at Tips-N-Tech.

AS/400 Tips-N-Tech
AS/400 tips, techniques, and FAQ. Updated frequently.
CODEPage/400
All the code samples you can eat! RPG, CL, DDS, etc. etc.
AS/400 FAQs
The official news400.com FAQs.






All AS/400 Tip Categories / AS/400 Programming / What's the fastest way to do a simple RPG lookup?


Question:

I sure you have all been here.

I want to make sure that the two character Unit of Measure code that my user has entered is valid. At the same time, for each code I want to have a corresponding description and equivalent X12 code. My first thought would be to have a 'Unit of Measure Code Master File' with the following fields.

UUNMSR, UNDESC, UUOMCD

With records like
EA      Each          EA
CS      Case          CA
BX      Box           CA
SP      Shelf Pack    PK
But my concern is the performance hit I would take chaining to this file so often, for example when creating a PO to be sent via X12 EDI I would have to chain to it for every detail record.

I definitely do not want to hard code this information into the programs that I want to use it on. I suppose I could load a multiple occurrence data structure with this info. But how do I perform the lookup? Are there other, better(?) ways to do this?


Answer(s):



Instead of loading the file into a multiple occurrence data structure, use an array. Then you could use a lookup function on the array to find the particular element you need.




Thanks for the reply. Maybe I am misunderstanding something here, but I thought that an array was made up of single elements. ie. an array of 10 two character codes. This would be fine for validation, but would not allow me to store the other two fields. Am I missing something here?




Yes. You missed the possibility to have other arrays contain the info you need!

For instance, you have the array with your unit of measure and find your user's input e.g. in element 2.

Then, you can access another array with your descriptions with index 2, and so on.

You can load the arrays at program initialization time from a file to avoid hardcoding (manually or by means of a prerun-time array [you'll find this in the RPG reference]), or, which is slightly more complicated, but also a common method, first lookup your array, and if you do not find it there, chain to a file. If you find it there, you can put it into the array(s). But I do not think that there is much performance won.

The AS/400 doesn't really access the hard disks every time to get records, OS/400 will move the stuff to the main storage, but you do not have to care about that.

A more difficult method, but performing very good, is the use of an user index, but that's not quite a point to start for a beginner.

Hope this helps!




Thanks for the reply. I hadn't thought of breaking the data up like that...I was thinking about working with the entire record as a whole from the file.




Yes. Alternate arrays are supported. This lets you define 2 arrays that are related. The first array would be your unit of measure. The second array would be a composite field of the description and X12 unit of measure. Use a data structure to split the second array into its subfields.

Normally I would just load the arrays in ordered sequence at initialization time and do a lookup for each record when the new lookup is differant from the prior lookup. This approach saves 1 disk I/O request per output record and minimizes the number of times lookup is actually executed.

I/O is much slower than lookup. Lookup is slower than reusing the prior values.




You don't need to use MO Arrays. You can define arrays in data structures, and even sort with them. For example:
DDS
D UOMArray  34DIM(100)
D  UOMKey    2          OVERLAY(UOMArray)
D  UOMDesc  30OVERLAY(UOMArray:3)
D  UOMCode    2OVERLAY(UOMArray:33)
Now, you load the fields by saying UOMKey(index) = xxx, UOMDesc(index) = xxx, and UOMCode(index) = xxx

This way you have all your fields together. If you wish to sort the arrays and keep the indecies intact, simply sort by the subfield of your choice. For example
 * sort by Description
C                SORTA          UOMDesc
 * sort by Code
C                SORTA          UOMCode
Alternating arrays, who needs em! This is the best array technique I have learned in years.




Thanks for the reply. You make some very valid points, especially about not doing the lookup if the last one is for the same code. Since 95% of my items are coded with the same code this should eliminate any performance problems.

I had already thought of this after my original post, but in the back of my mind I thought I remembered reading about something that was ideal to this scenario.




For a table of this size/complexity (not!), maybe you could just use SETOBJACC to load it into a small memory pool. Then, ignore thoughts of performance degradation. Other than that, if loading into an array doesn't suit your taste, I wouldn't even think twice about the performance aspect unless you're already hitting a performance curve -- in which case you've got other bigger problems.




If you only need to see if the entry made exists in your file you can do a SETLL using an indicator in the = position. This technique uses less overhead because no data is brought into the buffer at any time.

Also if you are using a CHAIN and the key value does not change from the previous CHAIN, the values still remain in the buffer. This is also less overhead than if the value changes and a read( disk)/write( buffer) actually occurs. It may be the same overhead or less than checking for a changed value in your program before chaining.




Just to test the performance hit, I wrote a small program to read the entire article file (88000 records) sequentially. On our model 620, this took 1.5 CPU secs. After adding a chain to our Unit of Measure file the program took 7.1 CPU secs. This shows that a chain takes a significant amouont of time (relatively). If you have a large AS/400 and/or a small article file, you probably won't bother if the job takes 5-10 secs. longer to execute.

If you do care, the methods suggested by others (array lookup or chain with array caching), will work fine. If you're using ILE you may write a function that checks the UOM code using SETLL (which requires less CPU than a chain), and functions to retrieve each of the corresponding UOM attributes. These routines may well use arrays, caching, or simply hardcoded data (since they're only specified in one source member, you can move them to a file later if you want to).




you make a wrong assumption here. If we talk I/O operations, CPU time is not a concern. The question is runtime. For each sync I/O, the cpu timeslice is ended and the job (after completing the I/o) will have to compete for a new timeslice again.




Database I/O is what the AS/400 is designed for. I can't imagine that a simple read to a code table can impact performance in a perceptible manner.

Certainly, the coding simplicity of a simple chain is much more desirable than the complexity of other approaches (arrays or data-structures). In many cases simplicity of code is much more desirable than the marginal improvement in response time a caching algorithm would give.

However, one thing you should do in whatever design you choose: don't do the lookup if the last lookup was for the same code. This technique alone can save a good percentage of necessary I/O.





Other tips in this category:

Click here to see all categories.

Socket Programming And Timeout Issues
Deleting Duplicate Records From A Table
What are data queues and how to use
Retrieving SMTP Name
RPGLE example for Dynamic Screen Manager API
Calling APIs from CL - with examples!
Compare two strings in RPG character by character
How to search all pgms in QCLSRC for a keyword
Retrieve Database File Description (QDBRTVFD) API
How to redirect the output to STDERR from RPG-IV
Using Multiformat Logical To Join 2 Identical File
D-Spec *LIKE DEFN
RPG: Converting Character to Decimal
Example of ILE RPG CGI Program
Handling ILE RPG Numeric Overflow
Help with Subfile Programming in RPG III
Zoned parameter in ILE RPG
What's the best way to do modulus in CL?
RPG Nesting Source Print Utility
More on changing the SIGNON screen
A silly ILE RPG question
Calling Validation List API From ILE RPG
Soft Coding Module Names
RPG Multidimensional Arrays in Action
Build a Page-Equals-Size Lookup Window
Procedures within an ILE RPG program
Break msg from RPG
Source Debugger for batch jobs
RPGLE debugging
Timing out display sessions in DDS
Building Dynamic Stored Procedures
Put Message in System Log
Dynamic RPGSQL
Randomize function for the AS/400
What's the fastest way to do a simple RPG lookup?
First time Data queue application in RPG
Print file overflow in ILE RPG
Mapping Fields To Arrays in ILE RPG
Named inidicators
STRQMQRY: comparision operator '=' isn't correct?!
DSPDTAARA to an outfile - possible?
PCL ESC codes in RPG
Sharing DB files between two AS/400s
Help: AS/400 subfiles
How do you change the signon screen?
Determining Even/Odd Values in queries
Get day of the week in RPG
Convert UPPERCASE to lowercase
RPG IV help using APIs
Help with data area API
Detecing IFS Files from RPG
SQL in a CL program
Calling AS/400 APIs from ILE RPG
CVTDAT command to convert an *MDY to a *LONGJUL
CPYSPLF Automation
Subfile Window background problem
Using IFS APIs w/ ILE RPG
Packed or unpacked fields?
QRYDFN to source and back
What does the "optimize" parm do?
Determining the calling program
Sockets in RPG?
Sorting a user space
OVRDBF and SECURE() keyword in an ILE environment
RPG record locking
RPG Differences: V2R3 to V3R2 upgrade
Getting the relative record number (RRN)
What is the longest parameter usable in RPG?
A C function that returns a string to an RPG pgm
Problems with ZADD *ZEROS
Can you highlight code in SEU?
Reusing deleted records - OK?
Is there an easy way to change edit codes?
Help - Windowed Subfiles
Logical Files and DDS
AS/400 'machine language' - MI Programming
Library lists and performance
How to use ERRSFL
Updating in CL
Record lock wait time
Message subfile problem
Physical File Joins
CL: Copying User Profiles
Commands and PARM
ILE RPG, RPG IV, vs. RPG/400
RPG and subfiles
Multiple subfiles
Field masking for passwords
SFLMODE keyword in an ILE program
Subfile size
Color coding records in a subfile
MSGLINE in windows
Controlling cursor movement on a display file
API returns error! Why?
Put an RPG Program on the Web
Variable length records in RPG
Differences Between RPG400, RPG IV, and ILE RPG


You are at a news400.com site.
Contact Us | Report Bugs | Submit Comments/Suggestions | Read Site Use Agreement | Read Privacy Policy
Copyright © 2000 Duke Communications International.
This site is best viewed with the latest versions of Netscape or Internet Explorer, 800 x 600 resolution (or higher), and at least 256 colors.
Duke Communications   NEWS/400 | 29th Street Press | Business Finance | DominoPro | Selling AS/400 Solutions | SQL Server Magazine | Windows NT Magazine