Boxed components and memory efficiency
What’s a boxed component?
I read about them first in this document – http://scn.sap.com/docs/DOC-26231. Then I read the release notes – you do read the release notes when you upgrade to a new abap version, don’t you? It’s worth doing, as you can find some very nice language enhancements. I read the sap help, but couldn’t quite get what the point of them was, nor how they worked.
Then I read this excellent blog SAP ABAP TYPE BOXED, New Type Category 7.02 Ehp2 – ABAP Help Blog that explains their functionality very clearly, but just now, I’ve created my first, real world use of the concept. So I’ll share it.
I’ve got some master data – materials and time dependent attributes. I’ve got a few million records of data that contain materials and dates, and I want to find the attributes for those material, at that particular date. The records I’ve got are in no particular order, may refer to the same material many times, and may well have materials that don’t have any master data. Also, the materials in my records are only a subset of all the possible materials.
Got that? Good.
The volume of master data is such that I cannot read all the data into an internal table in one go. So what I do is maintain a buffer that starts off empty. For a given material, I first check the buffer. If it isn’t there, I check the database. If I still don’t find anything I create a record in the buffer with a flag “not found”, If I do find something, then I add it to the buffer.
So, my line structure is something like: MATERIAL, CORRECTED_COST, CORRECT_CURRENCY, NOT_FOUND. Here’s some ABAP:
TYPES: BEGIN OF corrected_cost_ty, MATERIAL, CORRECTED_COST, CORRECTED_CURRENCY, NOT_FOUND, END OF corrected_cost_ty
Now, the problem is that if a material is NOT_FOUND, then it has no correct cost. So for all the NOT_FOUND data, there’s these two fields which never contain anything, but will be taking up space, nonetheless. This is where boxing comes in.
I create a type “attributes” which has CORRECTED_COST and CORRECT_CURRENCY, then I redo my corrected_cost_ty like this.
TYPES: BEGIN OF attributes_ty, CORRECTED_COST, CORRECTED_CURRENCY, END OF attributes_ty. TYPES: BEGIN OF corrected_cost_ty, MATERIAL, ATTRIBUTES type attributes_ty BOXED, NOT_FOUND, END OF corrected_cost_ty
Now, when I don’t have any attributes for a material (because it’s NOT_FOUND), memory is only allocated to the MATERIAL and NOT_FOUND.
Let’s say material is 18 bytes, not_found is 1 byte, corrected_cost is 17 bytes and corrected_currency 5 bytes. Then each of these records occupies 41 bytes. If we didn’t have a boxed structure, then all the records in my internal table would occupy 41 bytes. So if I had 6 entries, then that would be 246 bytes total. However, we do have a boxed structure, so the memory allocation looks something like this:
In this diagram, materials 1, 2 and 5 are not found, so their corrected costs and corrected currency are all initial. Boxing means that if the fields of the boxed part are initial, then every record that has these fields initial will share the same area of memory, for those fields. So these not found materials occupy 79 bytes, instead of (without boxing) 123 bytes.
The only downside of using boxing, is that I have to refer to my attributes as attributes-corrected_cost. I’d like to be able to use something like
INCLUDE TYPE attributes_ty BOXED.
But I guess we’ll have to wait a while for that to happen.