覆盖与查找

时间:2011-08-31 10:01:34

标签: java performance memory compiler-construction vm-implementation

我正在阅读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,还是编译语言的常识?

3 个答案:

答案 0 :(得分:5)

当然,右侧版本的等效 - 因为mGarbage设置为true 值是否已更改

左手边相当于原版,但没有意义。

基本上我认为你错过了检查现有值是否允许DELETED的副作用:它允许mGarbage设置为true 如果方法有实际上有一个效果。这与从数组中读取的性能无关。

答案 1 :(得分:2)

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

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

答案 2 :(得分:1)

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

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

  • mGarbage很可能是本地缓存,如果它是当前对象的字段值,可以是寄存器或L1缓存。您可能只是将对象放入缓存中,以便在几个周期之前执行类似虚拟方法查找的操作。当本地缓存某些内容时,读取或写入之间没有太大区别。
  • mValues [index]是一个不太可能被本地缓存的数组查找(特别是如果数组很大或只是偶尔访问)。由于锁定/内存争用问题,来自非本地缓存的读取通常比写入更快,因此如果您可以使用它,则只读取它是有意义的。您的计算机中拥有的核心越多,代码中的并发性就越高,这种效果就会越强。