覆盖与查找

问题描述 投票:0回答:3

我正在阅读android中的

SparseArray
类,并发现了以下方法:

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]
比数组写入更快,但变量查找并不比变量写入更快。

这是真的吗?它取决于VM,还是编译语言的常识?

java performance memory vm-implementation
3个回答
5
投票

当然,右侧版本等效 - 因为然后

mGarbage
设置为true无论值是否已更改

左边和原来是等价的,但是没有意义。

基本上,我认为您错过了检查现有值是否允许 DELETED 的副作用:它允许

mGarbage
设置为 true 如果该方法确实有效。这与从数组读取的性能无关。


2
投票

这在很大程度上取决于虚拟机,我猜这个特定的代码是针对 Dalvik 虚拟机进行调整的(或者它只是 Apache Harmony 碰巧实现的任何代码)。

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


1
投票

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

一般原因与数组和变量关系不大,但更多与内存访问模式有关:

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