|
Our group is thinking about encapsulating file access in service programs. Concerns have been voiced about the impact on performance such a move would have.
That entirely depends on how you write your code. There's no way we can even guess at the performance impact without having a good idea of how the code is intended to work.
Does anyone out there have practical experience with this technique that they would be willing to share?
My experience has been that you really need to start by defining what your goals and priorities are, so that you have a really good idea of what you hope to gain by doing this.
For example, if you write a service program that simply does the following:
D custRec E DS ExtName(CUSTMAS) P custmas_chain B D custmas_chain PI 1N D custno 4P 0 value D record like(custRec) /free chain custno CUSTMAS; record = custRec; return %found; /end-free P EWhat does it gain you to do this instead of chaining directly in the calling program? This doesn't make the database independent of that program, it still needs to know how the file works, how the fields are laid out, etc, in order to call this routine. This routine really doesn't gain you anything over using the RPG opcode directly.
Now, I'm not saying that separating the database logic is a bad idea -- it's not always a bad idea -- but you have to design it carefully. You need to decide ahead of time what the goals of doing so are, and you have to make sure that your design meets or exceeds those goals.
The code sample above does not have a big impact on performance. The only things that it affects are the time it takes to call the subprocedure, and the time it takes to copy the parameters. In comparison to the time it takes to access the record on disk, these things are very small.
However, what if you do the following? P custmas_chain B D custmas_chain PI 1N D custno 4P 0 value /free chain(e) custno CUSTMAS; return %found; /end-free P E P custmas_getName B D custmas_getName PI 30A /free return custName; /end-free P E P custmas_getAddr B D custmas_getAddr PI 30A /free return custAddr; /end-free P E P custmas_getCity B D custmas_getCity PI 15A /free return custCity; /end-free P E ... with more "get" routines, one for each field in CUSTMAS ...This code is better than the first code sample because it it helps keep the database separate from the calling routine. The program that calls this doesn't need to know the exact sizes of the fields, since they're returned by value and the system can do conversions. The program that calls it doesn't need to know the exact data types for the same reason. It doesn't need to know the from & to positions of the record, etc. So it really helps keep the database logic separate.
However, on the other hand, it also has a bigger impact on performance. You no longer are calling only one subprocedure when you load a record, you're now calling many of them, one for each field, and that'll hurt things. And, again, what have you gained? Is what you've gained enough that it makes sense to implement things this way?
Personally, I've found that what makes it the most valuable is to have it so that the module does MORE than just database access. Instead, have it do some business logic as well as simply loading the record.
As an Amazon Associate we earn from qualifying purchases.
This mailing list archive is Copyright 1997-2024 by midrange.com and David Gibbs as a compilation work. Use of the archive is restricted to research of a business or technical nature. Any other uses are prohibited. Full details are available on our policy page. If you have questions about this, please contact [javascript protected email address].
Operating expenses for this site are earned using the Amazon Associate program and Google Adsense.