Эффективная индексация в круговой буфер? - PullRequest
0 голосов
/ 04 апреля 2020

У меня есть некоторый код со следующей общей структурой:

const kmin = // arbitrary negative number
const kmax = // arbitrary positive number
const b = // buffer of size Z >= 2
for (let k = kmin; k <= kmax; k += 2) {
  // do stuff with b[k], b[k-1], and b[k+1]
}

, где b ведет себя как кольцевой буфер, поэтому индексы k >= Z должны возвращаться к началу, а индексы k < 0 должен обернуться до конца. Чтобы достичь этого, я сейчас делаю следующее:

for (let k = kmin; k <= kmax; k += 2) {
  const Zk = (k % Z) + Z; // 1 <= Zk < 2*Z
  const b_k = b[Zk % Z]; // 0 <= Zk % Z < Z 
  const b_km1 = b[(Zk - 1) % Z]; // 0 <= (Zk - 1) % Z < Z 
  const b_kp1 = b[(Zk + 1) % Z]; // 0 <= (Zk + 1) % Z < Z
  // do stuff with b[k], b[k-1], and b[k+1]
}

, что требует в общей сложности 4 % операций на каждую итерацию. Операции по модулю относительно дороги, и я хотел бы оптимизировать это, если это возможно. Если бы Z было степенью 2, то это можно было бы сделать с помощью быстрых операций с битовой маской ... но в целом этого нельзя ожидать; эта оптимизация может быть запущена только в очень редких случаях, что не оправдывает удвоение размера кода.

Есть ли какой-то другой более общий способ сделать это быстрее, или я просто застрял с 4 модовыми операциями после всех

...