防止在Java中分配ArrayList迭代器
因此,我在Android上写第一个游戏的过程中,在观看了一个关于游戏优化的冗长演示之后,我一直在检查我的分配情况。当ArrayList为for(Object o:m_ArrayList)约定创建一个隐式迭代器时,我已经设法摆脱了所有游戏中的分配,除了ArrayList中的分配 由于我的所有游戏对象、ai实体等都存储在这些迭代/分配中以便于使用,因此这些迭代/分配的数量相当少 那么我有什么选择呢防止在Java中分配ArrayList迭代器,java,android,iterator,allocation,Java,Android,Iterator,Allocation,因此,我在Android上写第一个游戏的过程中,在观看了一个关于游戏优化的冗长演示之后,我一直在检查我的分配情况。当ArrayList为for(Object o:m_ArrayList)约定创建一个隐式迭代器时,我已经设法摆脱了所有游戏中的分配,除了ArrayList中的分配 由于我的所有游戏对象、ai实体等都存储在这些迭代/分配中以便于使用,因此这些迭代/分配的数量相当少 那么我有什么选择呢 理论上,我可以指定合理的上界并使用数组,但我喜欢ArrayList的特性,比如保持代码干净和简单的e
- 理论上,我可以指定合理的上界并使用数组,但我喜欢ArrayList的特性,比如保持代码干净和简单的exists和remove
- 重写ArrayList并提供我自己的迭代器()实现,该实现返回一个类成员,而不是每次使用它时分配一个新的迭代器类型
提前感谢,很抱歉有这么多信息,但我认为这些信息可能对很多人有用。使用位置迭代
for ( int i = 0, n = arrayList.size( ); i < n; ++i )
{
Object val = arrayList.get( i );
}
或者在运行时
arrayList.ensureCapacity( numSlots );
对于奖金->我首先回答奖金问题:是的,
ArrayList
会预先分配插槽。它有一个将所需插槽数作为参数的构造函数,例如newarraylist(1000)
<代码>清除不会释放任何插槽
返回共享迭代器引用有一些问题。主要问题是您无法知道迭代器何时应该重置为第一个元素。考虑下面的代码:
CustomArrayList<Whatever> list = ...
for (Whatever item : list) {
doSomething();
}
for (Whatever item : list) {
doSomethingElse();
}
在这种情况下,您不希望在调用之间重置迭代器
@Alexander Progrebnyak的答案可能是在不使用迭代器的情况下迭代列表的最佳方式;只需确保您具有快速随机访问权限(即永远不要使用LinkedList
)
我还想指出的是,您正在进行一些非常繁重的微优化。我建议您在投入大量时间之前对代码进行分析,并找出分配迭代器是否是一个真正的问题。即使是在游戏中,你也应该只优化需要优化的内容,否则你可能会花很多很多天的时间从一分钟长的操作中减少几毫秒。谢谢,我确实考虑过这种方法,事实上我曾经使用过类似的方法,但在做了一点研究后被推迟了。与迭代器相比,get(i)函数的迭代速度似乎较慢。我想,这是因为节省了分配。。。。可能不得不experiment@makar. 实际上,对于ArrayLists
,get
将与使用迭代器一样快或更快。它直接引用底层数组的位置元素。在Java5之前没有这样做。迭代器在java中已经存在了很长一段时间。这很有趣,我会尝试找到任何让我不这么想的东西,如果我真的这么想的话。也许我在想其他的收藏品。@jtahlborn。你说得对!在Java5之前,迭代器就已经存在了,但是(for(objectobj:collection)
loop没有。我没有看到任何关于测试/评测的提及。这实际上是一个性能瓶颈吗?根据您的额外问题,没有初始容量参数的ArrayList构造最初会为列表中的10个对象分配空间,并在需要时按初始容量增长。您可以调用trimToSize
以节省空间。对于奖金问题,ArrayList默认分配10个容量@托马斯。潜在的,潜在的不是,在低规格的手机上偶尔会有暂停,我只能将其归因于GC,但无法100%确认。但是我想如果我可以用ArrayList替代其他类型的,那么这将是一个快速的胜利,没有任何负面影响。谢谢你的详细回答。我知道返回单个实例迭代器的相关风险,但如果这意味着停止分配,我很乐意遵守所需的规则。至于你们的另一点,我一直都很小心,不要在游戏中进行任何迭代,所以看到所有这些隐式分配都被吐出来有点令人沮丧!我抵制了过早进行大量优化的冲动,但我觉得如果我可以将ArrayList换成另一种类型,那么这将是一个快速修复,不会影响其他任何事情。但我明白了*不做任何分配。不是迭代。
CustomArrayList<Whatever> list = ...
for (Whatever item : list) {
doSomething();
}
for (Whatever item : list) {
doSomethingElse();
}
for (Whatever first : list) {
for (Whatever second : list) {
...
}
}