我有一个关于如何处理大量对象以提高性能的问题。我正在创建一个具有无限块状地形的2D游戏,显然这会带来一些性能问题。
我想出的方法是看看玩家的X值是否已达到1000的倍数,然后我将每个已经存在于保存文件或游戏世界中的块保存到文件。之后,我摧毁了游戏世界中的每个街区。之后,我循环浏览文件中保存的每个块,并测试它是否在某个半径范围内。如果是,我创建该块。
然而,我甚至不确定这是否有效。每当我达到1000的倍数时,游戏会冻结一两秒,并且在添加一些打印语句之后,似乎大部分时间都花在阅读文件上。是否有更好的方法来解决这个问题?
答案 0 :(得分:2)
我实际上自己正在制作这样的游戏,所以我的方法可能与您最适合的方式不同。
我个人使用谷歌的Guava caches之一,并有一个删除监听器。除了我手动删除对象之外的任何原因删除对象时,我将其写入磁盘。一个例子是:
LoadingCache<Position2D, BlockOfTiles> graphs = CacheBuilder.newBuilder()
.maximumSize(10000)
.expireAfterWrite(10, TimeUnit.MINUTES)
.removalListener(new MyTileMapListener())
.build(
new CacheLoader<Position2D, BlockOfTiles {
public Graph load(Key key) throws AnyException {
return loadFromDisk(key);
}
});
MyTileMapListner可能如下所示:
private class MyTileMapListener implements RemovalListener<Position2D, MyBlockOfTiles>{
@Override
onRemoval(RemovalNotification<K,V> notification){
if(notification.getCause()==RemovalCause.EXPLICIT) return;
writeToDisk(notification.getKey(), notification.getValue());
}
}
目前,尽管他们将大int[][][]
个数组作为字段,但我能够很好地保存30K对象。
提醒:缓存在内部创建线程。确保在尝试写入时至少使用基本同步来防止删除侦听器干扰主线程。像synchronized(
someCommonObject ){ // read or write }
这样简单的东西可以工作,如果公共对象是你的文件输出流或其他东西,它将是相当惯用的。像LevelDB 这样的数据库通常为你处理这个问题。