![]() |
Forum Index : Microcontroller and PC projects : String variables and the length qualifyer
Author | Message | ||||
panky![]() Guru ![]() Joined: 02/10/2012 Location: AustraliaPosts: 1114 |
I understand that the LENGTH qualifyier that can be used with string arrays does nothing on a normal string. In most of my programs I use dozens of string variables and most are very short (ie. less than 10 to 30 characters). A recent example is where I have 34 string variables - none of which are longer than 16 characters. With all strings normally being 256 characters in size, I am using 256 x 34 = 8705 bytes whereas if the length qualifyer could be used, I would only need 16 x 34 = 544 bytes! A very significant saving in large programs. So, my question is "would it be possible to have the length qualifyer also apply to normal string variables"? Perhaps one for Geoff or Peter? panky. ... almost all of the Maximites, the MicromMites, the MM Extremes, the ArmMites, the PicoMite and loving it! |
||||
TassyJim![]() Guru ![]() Joined: 07/08/2011 Location: AustraliaPosts: 6283 |
You could store them in an array. Jim VK7JH MMedit |
||||
Geoffg![]() Guru ![]() Joined: 06/06/2011 Location: AustraliaPosts: 3292 |
This is to do with the memory allocation algorithm. When you declare a string MMBasic will ask the memory management system for some RAM to store the string. This is allocated in chunks of 256 bytes which, in part, is why strings are limited to 255 bytes (the extra byte is used to record the string length). Even if you ask for 16 bytes you will still get 256 bytes. Memory allocation is a trade off between the chunk size and the efficiency of the algorithm. Large chunk sizes are more efficient to keep track of compared to small chunks. For the Micromite 256 byte chunks seemed about right. The other aspect is that Micromites have plenty of RAM anyway. For example, you have 32 string variables which take 8K but that is small compared to the 50K of free RAM that the humble 28-pin Micromite has (the MM+ has double this). Reducing the size of the memory allocated to each string would have little practical impact. Arrays of strings are a different matter. They can rapidly consume all the free RAM so MMBasic will ask for the array size times the LENGTH qualifier. The allocated memory will still have a minimum of 256 bytes and will be rounded up to make an integer number of 256 byte chunks but within that allocation many string elements can be stored. I hope that this makes sense. Geoff Geoff Graham - http://geoffg.net |
||||
TassyJim![]() Guru ![]() Joined: 07/08/2011 Location: AustraliaPosts: 6283 |
To add: A variable name takes up 32 bytes so by using an array you save those 32 bytes for each variable as well as making use of the LENGTH parameter. Jim VK7JH MMedit |
||||
Turbo46![]() Guru ![]() Joined: 24/12/2017 Location: AustraliaPosts: 1642 |
I agree Panky, I was surprised to learn only recently that the LENGTH qualifier didn't apply to normal strings. The MMBasic manual I have printed out says that it can be used for normal strings but I know it has been changed in later versions to say that it won't save any memory. While you could use an array, that doesn't allow for intuitive names for the individual strings and could make the code harder to read. Bill Edit: Sorry didn't see the last two posts. Keep safe. Live long and prosper. |
||||
panky![]() Guru ![]() Joined: 02/10/2012 Location: AustraliaPosts: 1114 |
Thanks Geoff, I understand and appreciate your detailed explanation, Best Regards, panky. PS. Thanks too, Jim, that is actually what I do to save as much space as possible. My program on the MM+ takes 720 blocks on download so I am nearing the limit - lots of comments so I use crunch on load which brings it back to some 400 odd blocks. ... almost all of the Maximites, the MicromMites, the MM Extremes, the ArmMites, the PicoMite and loving it! |
||||
robert.rozee Guru ![]() Joined: 31/12/2012 Location: New ZealandPosts: 2442 |
why do floats (4-bytes each) and integers (8-bytes each) not suffer from the same problem? cheers, rob :-) |
||||
matherp Guru ![]() Joined: 11/12/2012 Location: United KingdomPosts: 10315 |
Float and integer arrays do. So "DIM INTEGER a(1)" costs 256 bytes but so does "DIM INTEGER a(31)" Simple float and integer variables are stored in the variable table so just cost one variable. The union statement says that the 8 allocated bytes (based on the longest variable declaration - long long int) can be used by any of the variable types struct s_vartbl { // structure of the variable table char name[MAXVARLEN]; // variable's name char type; // its type (T_NUM, T_INT or T_STR) char level; // its subroutine or function level (used to track local variables) unsigned char size; // the number of chars to allocate for each element in a string array short int dims[MAXDIM]; // the dimensions. it is an array if the first dimension is NOT zero union u_val { MMFLOAT f; // the value if it is a float long long int i; // the value if it is an integer MMFLOAT *fa; // pointer to the allocated memory if it is an array of floats long long int *ia; // pointer to the allocated memory if it is an array of integers char *s; // pointer to the allocated memory if it is a string } val; }; |
||||
robert.rozee Guru ![]() Joined: 31/12/2012 Location: New ZealandPosts: 2442 |
aha, i think i understand! so is there a limit to the maximum number of simple variables allowed? or does the table just grow from the bottom of available RAM upwards, while the memory allocated for strings and arrays grows from the top of RAM down? then i presume there will be a fixed-size table for subroutines/functions (100 max on mx170), and fixed-size stacks for gosub/return, for/next, do/loop, and if/else/endif? a diagram showing all this would be a really useful addition to the micromite manual, to allow users a clearer understanding of how RAM is used. while it may be beyond some users to make sense of, others would no doubt find it useful. cheers, rob :-) |
||||
robert.rozee Guru ![]() Joined: 31/12/2012 Location: New ZealandPosts: 2442 |
it looks like each entry in the variable table is around 59 bytes: 32 + 1 + 1 + 1 + (8*2) + 8 this could be significantly reduced by instead of storing the variable name (32 bytes), one were to store a pointer (8 bytes) to the location in flash where the variable is declared plus a 1-byte name length. this would reduce each entry from 59 bytes down to 36 bytes. cheers, rob :-) |
||||
Geoffg![]() Guru ![]() Joined: 06/06/2011 Location: AustraliaPosts: 3292 |
Saving 23 bytes is trivial when the free RAM is 50K and the cost would be: - Slower searches - The extra flash to handle various terminators - It would break programs that rely on that structure (there are some) Geoff Graham - http://geoffg.net |
||||
JohnS Guru ![]() Joined: 18/11/2011 Location: United KingdomPosts: 4044 |
I suppose someone desperate to save some RAM and willing to make the internals slower and more complex (and perhaps with more bugs which are harder to find) could ask for the source and make the changes to their local MMBasic. Or use a CPU with more RAM. John |
||||
![]() |
![]() |
The Back Shed's forum code is written, and hosted, in Australia. | © JAQ Software 2025 |