【问题标题】:Efficient alternative to Stack<Double>Stack<Double> 的有效替代方案
【发布时间】:2016-10-01 22:14:42
【问题描述】:

我正在用 Java 编写一个性能关键的方法,它使用一堆 double 值来存储点的 (x, y) 坐标。目前,我正在使用Stack&lt;Double&gt;,但我意识到由于自动装箱的成本,这可能会导致一些性能问题。坐标通常在调用之间发生变化,这就是为什么缓存 Double 包装器无济于事。

因此,我正在寻找一个假设的类,我们称之为DoubleStack,其行为和接口类似于Stack&lt;T&gt;,但仅对原语进行操作。是否有一个经常使用的具有这种行为的类,或者更好的是,一个由流行容器(包括列表、堆栈和队列)的主存储替代品组成的库?

【问题讨论】:

  • 堆栈是适合您算法的数据结构吗?如果是这样,请忽略可能的性能问题,直到您有确凿的证据表明堆栈是性能瓶颈。如果您遇到性能问题,您应该分析您的代码并投资于分析器认为速度较慢的领域。你现在正在做的是Premature Optimization
  • 如果堆栈确实是性能瓶颈,我想您可以轻松地基于double[] 实现自己的数据结构。所需的代码量不会太多,特别是如果您不需要实现Stack&lt;T&gt; 的所有接口,但仍然足够我建议遵循 Jim 的建议。
  • 使用您选择的搜索引擎搜索“java原始集合”;您会找到执行此操作的库。
  • 有很多库支持原始包装器,但没有一个只是堆栈。

标签: java generics stack primitive


【解决方案1】:

我同意关于过早优化的评论,但只是为了好玩,这里有一个简单的 DoubleStack 实现:

public class HeresYourDoubleStack {
  private int size = 0;
  private double[] values= new double[16];

  public int size() {
    return size;
  }

  public double pop() {
    if(size==0)throw new NoSuchElementException();
    return values[size--];
  }

  public void push(double value) {
    resizeIfNecessary();
    values[size++]=value;
  }

  private void resizeIfNecessary() {
    if(values.length==size){
      double[] tmp = new double[size * 2];
      System.arraycopy(values,0,tmp,0,size);
      values=tmp;
    }
  }
}

未经测试,绝对不是线程安全的。

【讨论】:

    【解决方案2】:

    有几个库为基本类型提供数据结构。 一个例子是FastUtil,它提供了一个类DoubleStack,它完全可以满足您的需求。 一个替代方案可能是Trove4J,它提供了一个类TDoubleStack,并且可能还有其他库,但我使用过的两个库。

    Trove4J 长期以来一直是一种标准,但似乎不再有很多更新,而 FastUtil 似乎得到了更积极的开发。此外,在我的一些(有偏见的?)测试中,FastUtil 在许多情况下更快,尽管我主要测试的是 Maps,而不是 Stacks。

    【讨论】:

    猜你喜欢
    • 2011-09-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-08-13
    • 2010-09-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多