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 |