2

我正在阅读SparseArrayandroid中的课程,并遇到了以下方法:

public void removeAt(int index) {
    if (mValues[index] != DELETED) {
        mValues[index] = DELETED;
        mGarbage = true;
    }
}

显然,这也可以写成:

public void removeAt(int index) {      Or   public void removeAt(int index) {
    if (mValues[index] != DELETED) {            mValues[index] = DELETED;
        mValues[index] = DELETED;               mGarbage = true;
        if (!mGarbage)                      }
            mGarbage = true;         
    }                                
}                                    

看起来 android 开发人员认为数组查找mValues[index]比数组写入快,但变量查找并不比变量写入快。

这是真的吗?它是否依赖于虚拟机,或者它也依赖于编译语言的一般知识?

4

3 回答 3

5

当然右边的版本是等价的——因为 thenmGarbage设置为 true无论值是否改变

左边和原来的一样,但是没有意义。

基本上我认为你已经错过了检查现有值是否允许删除的副作用:只有当方法实际产生影响时,它才允许mGarbage设置为 true 。这与从数组读取的性能无关。

于 2011-08-31T10:03:29.080 回答
2

这在很大程度上取决于 VM,我猜这个特定的代码是为 Dalvik VM 调整的(或者它只是 Apache Harmony 碰巧实现的任何东西)。

要记住的一件事是,写入总是意味着一些与缓存和跨线程交互相关的成本(即,您可能需要内存屏障才能使其正常工作),而读取则更容易做到。

于 2011-08-31T10:07:01.017 回答
1

这个假设可能是正确的,尽管它在很大程度上取决于处理器和 JVM 实现。

一般原因与数组与变量的关系不大,而与内存访问模式有关:

  • 如果 mGarbage 是当前对象的字段值,它很可能会在本地缓存,无论是在寄存器中还是在 L1 缓存中。您可能只是将对象放入缓存中,以便在几个周期前执行虚拟方法查找之类的操作。当本地缓存某些内容时,读取或写入之间不会有太大区别。
  • mValues[index] 是一种不太可能在本地缓存的数组查找(特别是如果数组很大或只是偶尔访问)。由于锁定/内存争用问题,从非本地缓存读取通常比写入快,因此只有在可以摆脱它的情况下才进行读取是有意义的。机器中的内核越多,代码中的并发性越多,这种效果就会越强。
于 2011-08-31T10:10:17.637 回答