ByteArray Beats Regular Array

Posted in Methodology, Programming on April 21st, 2009 by Manuel
No Gravatar

To compare the performance of different approaches for handling large data I wrote a small test suite.

This application contains one test class (cDataHandlingTest) that writes to and reads from an abstract data class (iData). Each data class offers an unified interface but is implemented in different ways. The test class repeats each test several times, records initialization times and accessing times and then calculates the average for each data class. If you want to have a closer look on the code, you can download the FlashDevelop-project here. You can check out the test application at the end of the post.

Three-Dimensional Array (cDataArray3D)

This data class uses a three-dimensional array to store the data. Initialization takes a very long time because you need to cycle through several nested loops allocating the data. Access times are ok.

Linear Array (cDataArray1D)

Here I used a linear array for the data. Initialization for a linear area is lightning fast. The draw-back is the access, though. Calculating the offset of the data in the array is pretty complex:

var index:int = (((_y * m_width ) + _x) * m_entries) + _entryType;

This makes working with a linear array really slow if you cannot predict in what order you will access the data. If you will usually access the data in the exact order it is stored in the array, you would actually be really fast. Unfortunately, this is usually not the case. The linear array is about 10 times slower than the three-dimensional one on random access.

ByteArray Int-Based Access (cDataArrayByte)

In this example I used a ByteArray. The position is calculated in the exact same way as in the linear array example. Data is extracted by using a readInt() command on the stream, data is written by using the writeInt() command. I expected this approach to be really slow. Well it isn’t! On my computer it already outperforms the three-dimensional array in all areas. (It might not on others, though).

ByteArray Byte-Based Access (cDataArrayByteOpt)

If you only need values between 0 and 255 you can use the array operator [ ] of the ByteArray class. This is the fastest way to access the data. Initialization times are really good and access is on my computer about 25% faster than the three-dimensional array.

Test Application

This is the test. Click into the window to start. Be careful, it needs a lot of resources. If you have significantly less then 2GHz per core or only one core I recommend not to try it because it will lock up your computer for too long to be convenient.

Popularity: 7% [?]

  • Share/Bookmark
Tags: , , , , , , ,

Handling large data with AS3

Posted in Programming on March 30th, 2009 by Manuel
No Gravatar

We decided to do our map generator in Flash. One of the reasons was we can share the render code between game client and generator this way. We are planning on having really big maps in our game. To be on the safe side I quadrupled the requirements made by game design (well, you never know) and ended up with more than 10 million values to stuffed into memory. Each map position has different values such as terrain type, climate zone, humidity and height level, … so this is really a lot of data!

With such large data blocks I was facing three problems: One is data initialization time, another one is access time and the last one is memory footprint.

In the first iteration of my map-data class I used our extensive and comfortable dynamic property system. I thought it would be a good idea if I could add any amount of arbitrary data to any map entry. This freedom came with big price tag: It took forever to initialize and used about one Gigabyte of memory. This was absolutely not acceptable!

Consequently, this was not the way to go. Next, I tried a three-dimensional array. This approach makes the data a bit less flexible but it’s still ok. Initialization time was better but still not great. The memory footprint wasn’t what I would call good either. At least, I was now able to fit the data into memory (we’re still talking about over 100MB, though). To bring down initialization times I refactored the data class to use a linear array. Linear arrays are really fast to create, but then I realized that access times are terrible. So, I did not find a satisfying solution here either.

More or less by accident I stumbled over Flash’s built-in ByteArray class. It is basically works as a stream so I did not expect a great performance gain. I tried it anyway. Well, it really outperformed the three-dimensional array, which is astounding since the ByteArray needs the same offset calculations as the linear array does. The best thing about the ByteArray is it’s memory footprint. There is no class overhead and if you only need values between 0 and 255 (as I did) you can use one byte per value instead of wasting 4 bytes (size of int) each. This brought down the required memory to around 10 MB.

In my next post I will write about a little test suite I wrote to prove the power of the ByteArray. So stay tuned and remember to give ByteArray a chance.

Happy coding! :)

Popularity: 5% [?]

  • Share/Bookmark
Tags: , ,