Header Names - Memory Effect

Prev Next

Benefit - Increasing Performance

In order to increase overall performance, all header names which are explicitly mentioned with string values, for example [Family Name], ['Family Name] or ["Family Name], the physical column position of these headers will normally be identified only once by comparing all headers from left to right, and are then memorized. behind the header name. This will improve the performance when processing through entire tables whiles referencing the same headers, e.g.

table process( table, [Full Name] = [First Name] + ' ' + [Last Name] ). Beginning with the 2nd round, the column positions of Full Name and First Name are known and referencing these columns becomes much faster, especially on very large tables containing many columns.

Note: Column numbers will not be memorized if variables, table references or any expressions with some algorithems are used instead.

Attentions - Memorized Columns can Strike Back!

In a different case, you create a user-defined function which proceses a particular table and refernce the colum numbers. See following example:

       table initialize ( table 1, { { Animal, leg count }, { Bird, 2 }, { Dog, 4 }, { Fly, 6 } } );
       table initialize ( table 2, { { Animal, weapon, leg count }, { Snake, poison, 0 }, { Tiger, teeth, 4 }, { Lobster, claws, 8 } } );

       define procedure ( legs, { { table name, string } } )
       {
               table process( table name[], echo( str([Animal],"8#" ),": ", [leg count] ) );
       }

       legs( table 1 );
       legs( table 2 ); // Note: Weapons are listed and not the legs
Bird    : 2
Dog     : 4
Fly     : 6
Snake   : poison
Tiger   : teeth
Lobster : claws
Try it yourself: Open LAN_Features_memory_effect.b4p in B4P_Examples.zip. Decompress before use.

Solving the Drawback

The column numbers for 'Animal' and 'leg count' are memorized after their first reference, and becomes an issue when called with the 2nd table where the "leg count" lies in a different column further to the right and a column called "weapon" has taken is place there. The 2nd function call lists the weapons.

Three different approches are available to solve this issue:

  • Instead of referencing the text value directly, do a simple calculation with it, e.g. putting parentheses around them: [(Full Name)]
  • Force B4P to forget the column numbers in the current program by calling forget memorized table columns()
  • Deactivate memorizing by changing runtime settings

Using Parentheses:
       table initialize ( table 1, { { Animal, leg count }, { Bird, 2 }, { Dog, 4 }, { Fly, 6 } } );
       table initialize ( table 2, { { Animal, weapon, leg count }, { Snake, poison, 0 }, { Tiger, teeth, 4 }, { Lobster, claws, 8 } } );

       define procedure ( legs, { { table name, string } } )
       {
               table process( table name[], echo( str([Animal],"8#" ),": ", [(leg count)] ) );
       }

       legs( table 1 );
       legs( table 2 );
Note the right output of leg count
Bird    : 2
Dog     : 4
Fly     : 6
Snake   : 0
Tiger   : 4
Lobster : 8
Try it yourself: Open LAN_Features_memory_effect_01.b4p in B4P_Examples.zip. Decompress before use.

You can apply the parentheses where you suspect table columns to shift. The position of the column will then be recalculated every time it is referenced. For the example code, it's six times.

Consider Forgetting Column Positions

Alternativly, consider B4P to become forgetful using the function forget memorized table columns(). This is a one-time acction over the entire code in the currently loaded and running B4P program file, covering all code lines.

In the following program example, the column number for 'leg count' will be forgotten and re-memorized every time the user-defined function is called again. The advantage of this compared to adding simple algorithmes like parentheses around header names is that you ill not have a performance comprormise particularly for very large tables since the header positions will only be calculated once after having them forgotten.

Let B4P forget memorized columns:
       table initialize ( table 1, { { Animal, leg count }, { Bird, 2 }, { Dog, 4 }, { Fly, 6 } } );
       table initialize ( table 2, { { Animal, weapon, leg count }, { Snake, poison, 0 }, { Tiger, teeth, 4 }, { Lobster, claws, 8 } } );

       define procedure ( legs, { { table name, string } } )
       {
               forget memorized table columns; // All memorized columns in this B4P program file will be forgotten
               table process( table name[], echo( str([Animal],"8#" ),": ", [leg count] ) );
       }

       legs( table 1 );
       legs( table 2 );
The output is OK
Bird    : 2
Dog     : 4
Fly     : 6
Snake   : 0
Tiger   : 4
Lobster : 8
Try it yourself: Open LAN_Features_memory_effect_02.b4p in B4P_Examples.zip. Decompress before use.

Deactivate Memorizing

Finally, the brute force appraoch is to disable all columns being memorized. This makes programming very safe, but may also slow overall performance a bit, particularly if the tables contain many columns, because the header name provided is compared with the existing table header names every time. You can disable it by setting the system variable runtime settings[memorize table columns] to false. This setting will apply until the B4P program has ended or the variable has been enabled again.

Disable memorizing
       table initialize ( table 1, { { Animal, leg count }, { Bird, 2 }, { Dog, 4 }, { Fly, 6 } } );
       table initialize ( table 2, { { Animal, weapon, leg count }, { Snake, poison, 0 }, { Tiger, teeth, 4 }, { Lobster, claws, 8 } } );

       define procedure ( legs, { { table name, string } } )
       {
               table process( table name[], echo( str([Animal],"8#" ),": ", [leg count] ) );
       }

       runtime settings[memorize table columns] = false;
       legs( table 1 );
       legs( table 2 );
The output is OK
Bird    : 2
Dog     : 4
Fly     : 6
Snake   : 0
Tiger   : 4
Lobster : 8
Try it yourself: Open LAN_Features_memory_effect_03.b4p in B4P_Examples.zip. Decompress before use.