I am working on porting a Roguelike dungeon adventure game to the Android.
http://tyrant.sourceforge.net
When I start my program, I initialize the world and all it’s objects first. I have a class that contains 3 million(!) HashMap entries. When I try to initialize that class, it takes 5+ minutes to run on my Android, which is a very unacceptable length of time. Once the class is is initialized, the game runs great and is quite fun.
So I thought I could serialize this object and reload it at runtime. I serialize it, and pack it in the .APK file, it’s over 5MB in size. Android just chokes and gives me an OutOfMemory error.
I can deserialize part of the class(800KB), and then dynamically create the rest of entries. That still takes quite a few minutes to finish too, it still has to create 3 million entries from the serialized data. But I do know that my serialization code works fine.
How can I store this very large class file on the Android and load it later? What are some options I can explore? Making my user wait 5 minutes for the app to start is not very good at all.
Here is the troubling class in the original source code:
http://tyrant.cvs.sourceforge.net/viewvc/tyrant/tyrant/mikera/engine/Lib.java?view=markup
and the troubling field is:
private transient Map types;
(I’m aware it’s transient)
it ends up storing over 3 million entries!
Well part of the problem is what is in the
typesmap.From what I can make out, it is effectively a
Map<String, Map<Integer, List>>, where the 2nd level maps are really non-sparse arrays. If you chose a better data structure it would occupy less space and you could build it much faster. (I think you are right not to serialize it … since it looks like it might not be changed during game play.)A
HashMap<Integer, Object>takes a LOT more space than anObject[].A better data structure would be
Map<String, LevelMap>whereLevelMapis something like this: