Read/Write Array to disk
Blitz3D Forums/Blitz3D Beginners Area/Read/Write Array to disk
| ||
| Hi, I have a (320,240) array of data that I need to write to and read from disk. What is the most efficient way of doing this? This is an integer array, where each value is either 0 or 1. I currently convert these to a single binary string that where each position is a binary value of either CHR$(0) or CHR$(255). This gets written to disk, and loaded again. This means I end up with a single string with 76800 positions that then get parsed out into an array again:
For x=0 To 319
For y=0 To 239
If Mid$(GfxOverlay$(2),(x+1)+(y*320),1)=Chr$(255)Then
walkability(x,y)=1
Else
walkability(x,y)=0
End If
Next
Next
The time it takes to write the info to disk is not very important (It is game level information, which gets created once, but loaded many times) The time it takes to load the data from disk and rebuild the original array does need to be as short as possible though. Is there a faster/better way or writing a full array, or am I on the right track? I *figure* it will be faster to load a 77K string in one go and parse it out, than 77K individual variable reads... But I may be missing something entirely here. Thoughts, anyone? |
| ||
why don't you just use writebyte and readbyte; ;save ; fileout=writefile(filename$) for x=0 to 319 for y=0 to 239 writebyte(fileout,myaray(x,y)) next next closefile fileout ; ;load ; filein=readfile(filename$) for x=0 to 319 for y=0 to 239 myaray(x,y)=readbyte(filein) next next closefile filein so no need to convert anything to any other thing = gain of speed !! |
| ||
| I haven't clocked this yet, but I do know that in other (older) languages it could be *insanely* slow to read a byte at a time from disk - loading a larger chunk all at once could sometimes be thousands of times faster, hence my conversion to a string first... Anyway, I guess I'll do some benchmarking. :-? |
| ||
| your o/s will read the file in chunks, not a byte at a time so no need to worry about that. |
| ||
| If you're concerned about load times, write it out as 320 strings of 240 characters each. Then you can read them back in a line at a time (and then break the string down once you've read it in). |
| ||
| If you only need to load a single array of that size it doesn't matter much, virtually instant anyway. You could save it as 1-bit bitmap, and then presume that standard imageloading is done fast, but then you would have to convert the image to an array, if it's about speed. Well, don't bother if it's not a problem. |
| ||
You don't need to use Chr$(0) and Chr$(255) to store it...Chr$(0) and Chr$(1) would work just fine...here is a way to write/load the array:
;savearray
Temp$="" ;clear the temp string
For x=0 to 319; or 1 to 320...whichever way you are doing it
For y=0 to 239; or 1 to 240...
temp=temp + chr$(array(x,y))
Next
Next
file = openfile("myfile.dat")
Writestring(file,temp) ;writes the string all at once in binary forum
Closefile file
;to load the the array
Temp$="" ;clear the temp string
Openfile("myfile.dat")
Readstring file,temp
Closefile file
counter = 1
For x = 0 to 319 ; or 1 to 320
For y = 0 to 239 : or 1 to 240
array(x,y) = Asc( Mid$( temp, counter, 1))
counter = counter + 1
Next
Next
also...if the array is nothing but bit values (1 and 0) why not save a whole hell of a lot of memory by useing the individual bits of an integer to store the values...so instead of useing 4 bytes (32-bits) to store a 0 or 1...use each of the 32 bits, then useing bitwise operations to test/set them? It's a little more complicated to set-up and use...but you can go from useing a 320 X 240 integer array of 32-bit integeres (approx 300k...while your chr$() basied storage method of one byte per bit value uses some 75k)...you can reduce this down to an integer array of 10 X 240 which is 9.4k?...then when checking if the bit is set...arrayindex% = testX / 32 : bitoffset% = testX MOD 32...and to check the bitvalue....check = (array(arrayindex, testY) shr bitoffset) AND 1 |