Перезапись против поиска - PullRequest
2 голосов
/ 31 августа 2011

Я читал через SparseArray класс в Android, и наткнулся на следующий метод:

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] был быстрее записи массива, но поиск переменной был не быстрее записи переменной.

Действительно ли это так?Зависит ли это от виртуальной машины или это общие знания и в скомпилированных языках?

Ответы [ 3 ]

5 голосов
/ 31 августа 2011

Конечно, правая версия не эквивалентна - потому что тогда mGarbage устанавливается в true независимо от того, изменилось ли значение .

.левая сторона эквивалентна оригиналу, но это бессмысленно.

В основном я думаю, что вы пропустили побочный эффект проверки того, было ли существующее значение разрешено DELETED: это позволяет mGarbage бытьустановите в значение true только , если метод действительно имел эффект.Это никак не связано с производительностью чтения из массива.

2 голосов
/ 31 августа 2011

Это сильно зависит от виртуальной машины, и я предполагаю, что этот конкретный код настроен для виртуальной машины Dalvik (или это просто то, что Apache Harmony реализовал).

Следует помнить, что запись всегда подразумевает некоторые затраты, связанные с кэшированием и межпотоковым взаимодействием (т. Е. Для корректной работы могут потребоваться барьеры памяти), тогда как чтение намного проще.

1 голос
/ 31 августа 2011

Предположение, вероятно, верно, хотя оно будет во многом зависеть от процессора и реализации JVM.

Общая причина заключается не столько в массивах или переменных, сколько в шаблонах доступа к памяти:

  • Скорее всего, mGarbage будет локально кэширован , если это значение поля текущего объекта, либо в регистре, либо в кэше L1.Вы, вероятно, просто помещаете объект в кеш, чтобы сделать что-то вроде поиска виртуального метода несколько циклов назад.Не будет большой разницы между чтением или записью, когда что-то локально кэшируется.
  • mValues ​​[индекс] - это поиск в массиве, который с менее вероятно будет локально кэшироваться (особенно еслимассив большой или доступ к нему происходит только время от времени).Чтения из нелокальных кэшей обычно выполняются быстрее, чем записи, из-за проблем с блокировкой / конфликтом памяти , поэтому имеет смысл выполнять чтение только в том случае, если вам это сойдет с рук.Этот эффект становится тем сильнее, чем больше ядер у вас на компьютере и тем больше параллелизма в вашем коде.
...