gpt4 book ai didi

java - 我怎样才能在 Android 上反序列化一个非常大的类?

转载 作者:行者123 更新时间:2023-11-29 09:22:25 25 4
gpt4 key购买 nike

我正在努力将 Roguelike 地牢冒险游戏移植到 Android。 http://tyrant.sourceforge.net

当我开始我的程序时,我首先初始化世界和它的所有对象。我有一个包含 300 万(!)个 HashMap 条目的类。当我尝试初始化该类时,在我的 Android 上运行需要 5 分钟以上,这是一个非常 Not Acceptable 时间长度。初始化类后,游戏运行良好且非常有趣。

所以我想我可以序列化这个对象并在运行时重新加载它。我序列化它,并将它打包到 .APK 文件中,它的大小超过 5MB。 Android 突然卡住了,给我一个 OutOfMemory 错误。

我可以反序列化部分类 (800KB),然后动态创建其余条目。这仍然需要几分钟才能完成,它仍然需要从序列化数据中创建 300 万个条目。但我知道我的序列化代码工作正常。

如何在 Android 上存储这个非常大的类文件并在以后加载它?我可以探索哪些选项?让我的用户等待应用程序启动 5 分钟一点都不好。

这是原始源代码中令人不安的类: http://tyrant.cvs.sourceforge.net/viewvc/tyrant/tyrant/mikera/engine/Lib.java?view=markup

令人不安的领域是:

private transient Map types;

(我知道这是暂时的)

它最终存储了超过 300 万个条目!

最佳答案

部分问题在于 types 中的内容 map 。

据我所知,它实际上是一个 Map<String, Map<Integer, List>> ,其中第二级映射实际上是非稀疏数组。如果你选择了一个更好的数据结构,它会占用更少的空间,你可以更快地构建它。 (我认为你不序列化它是对的......因为它看起来在游戏过程中可能不会改变。)

A HashMap<Integer, Object>Object[] 占用更多空间.


更好的数据结构应该是Map<String, LevelMap>其中 LevelMap是这样的:

public class LevelMap {
private static final ArrayList<String> EMPTY = Collections.emptyList();

private ArrayList<String>[] levels;
private int firstLevel;

public LevelMap(int firstLevel, int lastLevel) {
this.firstLevel = firstLevel;
levels = new ArrayList<String>[lastLevel - firstLevel + 1];
}

public static void addToTypeMap(String key, String value,
int firstLevel, int lastLevel) {
LevelMap l = types.get(key);
if (l == null) {
l = new LevelMap(firstLevel, lastLevel);
types.put(key, l);
}
l.add(value, firstLevel, lastLevel);
}

public void add(String value, int firstLevel, int lastLevel) {
ensure(firstLevel, lastLevel);
for (int i = firstLevel; i <= lastLevel; i++) {
j = i - this.firstLevel;
if (levels[j] == null) {
levels[j] == new ArrayList<String>();
}
levels[j].add(value);
}
}

private void ensure(int firstLevel, int lastLevel) {
// Make sure that these levels are in the levelmap
// If necessary, reallocate this.levels and adjust this.firstLevel
}

public String get(int level) {
if (level < this.firstLevel ||
level >= this.firstLevel + levels.length ||
levels[level - this.firstLevel] == null) {
return EMPTY;
} else {
return levels[level - this.firstLevel];
}
}
}

关于java - 我怎样才能在 Android 上反序列化一个非常大的类?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5428949/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com