【问题标题】:Java - no-duplicate collection without iterator allocationJava - 没有迭代器分配的无重复集合
【发布时间】:2019-02-20 14:13:43
【问题描述】:

问题

我正在开发一款需要最小化内存分配和 GC 活动的游戏。为此,我需要一个具有非重复值的集合,以最大限度地减少访问操作期间的内存分配。我准备妥协以稍微降低性能来弥补改进的“垃圾生成”。

考虑的解决方案(包括废弃的供参考)

  1. 扩展 ArrayList 以包括对 add(E e) 的重复检查,如果值存在则不执行任何操作。 (这也可能包括其他方法)
  2. 使用 HashSet(废弃) - 元素的迭代会导致新迭代器的实例化,这违反了访问期间最小内存分配的要求。
  3. 将 HashSet 转换为 ArrayList(丢弃) - 创建比 HashSet 迭代更多的内存分配。

问题

ArrayList 的扩展以防止重复值是一种以最少的内存分配实现非重复收集的明智方法吗?我应该考虑其他方法吗?

备注

我见过的消除 ArrayList 中重复项的最推荐解决方案是指使用 HashSet 或其他对象实例化,这会破坏我的最小内存分配要求。我能想到的唯一实现是 ArrayList 的基本“迭代”检查每个现有元素的附加值是否相等。

Class NonDuplicateList extends ArrayList{
    @Override
    boolean add(E e){
        for(int i = 0; i < this.size(); i++){
            if(this.get(i).equals(e)
                return false;
        }
        return super.add(e);
    }
}

【问题讨论】:

  • 一个Iterator 对象在内存方面相当便宜。我想知道您是否不要太快得出结论等等您的要求。
  • @davidxxx 它“相当便宜”,但在游戏环境中(大量访问操作和低延迟要求)它加起来。我很欣赏对这种利基问题的怀疑,但总体目标是在游戏框架生命周期中获得接近零的分配,通常你可以通过池/重用对象来实现这一点,这在迭代器方面是相当成问题的。
  • 附注如果内存使用是一个大问题,您可能需要考虑使用 LinkedList,这样您也不会进行任何调整大小操作。

标签: java memory-management game-engine


【解决方案1】:

你这里的不是ListList.add,按照合同,必须返回true

返回:

true(由Collection.add(E)指定)

您可以改为使用IllegalArgumentException

投掷:

IllegalArgumentException - 如果这个元素的某些属性阻止它被添加到这个列表中

但必须处理异常是很糟糕的。

此外,扩展ArrayList很少是正确的做法:在这种情况下,ArrayLists 允许您将任何元素添加到末尾(只要有足够的内存),所以你的课程不能被 Liskov 替代。

另外,当然,您必须覆盖所有其他允许您将元素添加到列表的方法:add(其他重载)、addAllset、@987654334 上的所有方法@ 和 listIterator 等等。这很难正确地做到。


改为使用构图

class NonDuplicateList<E> {
    private final List<E> delegate = new ArrayList<>();

    boolean add(E e){
        // contains is easier! ArrayList.contains does not use an iterator.
        if (delegate.contains(e)) return false;
        return delegate.add(e);
    }

    // Other methods you may require
}

通过像这样定义自己的类,您不需要遵守任何不是您自己设计的契约;并且您可以公开更少的方法集,从而大大减少维护列表的 no-duplicates 属性的工作量。

【讨论】:

  • 谢谢,当然更清晰地实现了这个概念。
  • 为了记录,我实现了不重复的 ArrayList 解决方案(通过组合)替换基于迭代器的访问,并且 GC 暂停图现在是一条很好的平线 :-)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-04-25
  • 2012-03-23
  • 1970-01-01
  • 1970-01-01
  • 2012-07-03
  • 2015-08-17
相关资源
最近更新 更多