Циркулярный прирост: что лучше? - PullRequest
6 голосов
/ 10 мая 2010

Если у вас есть циклический буфер, представленный в виде массива, и вам нужен индекс для переноса (т. Е. Когда вы достигнете максимально возможного индекса и увеличите его), лучше ли вам:

return (++i == buffer.length) ? 0: i;

или

return ++i % buffer.length;

Есть ли у оператора modulo какие-либо недостатки? Это менее читабельно, чем первое решение?

EDIT:

Конечно, это должен быть ++ i, а не i ++, это изменилось.

РЕДАКТИРОВАТЬ 2:

Одно интересное примечание: я нашел первую строку кода в реализации ArrayBlockingQueue Дуга Ли.

Ответы [ 12 ]

0 голосов
/ 01 июля 2014

Вы также можете использовать битовые манипуляции:

idx = idx & ((idx-length)>>31)

Но это не быстрее, чем вариант if на моей машине.

Вот код для сравнения времени выполнения в C #:

Stopwatch sw = new Stopwatch();
long cnt = 0;
int k = 0;
int modulo = 10;

sw.Start();
k = 0;
cnt = 0;
for ( int j=0 ; j<100000000 ; j++ ) {
    k = (k+1) % modulo;
    cnt += k;
}
sw.Stop();
Console.WriteLine( "modulo cnt=" + cnt.ToString() + "     " + sw.Elapsed.ToString() );
sw.Reset();


sw.Start();
k = 0;
cnt = 0;
for (int j = 0; j < 100000000; j++) {
    if ( ++k == modulo )
        k = 0;
    cnt += k;
}
sw.Stop();
Console.WriteLine( "if     cnt=" + cnt.ToString() + "     " + sw.Elapsed.ToString() );
sw.Reset();

sw.Start();
k = 0;
cnt = 0;
for (int j = 0; j < 100000000; j++) {
    ++k;
    k = k&((k-modulo)>>31);
    cnt += k;
}
sw.Stop();
Console.WriteLine( "bit    cnt=" + cnt.ToString() + "     " + sw.Elapsed.ToString() );

Выход:

modulo cnt=450000000     00:00:00.6406035
if     cnt=450000000     00:00:00.2058015
bit    cnt=450000000     00:00:00.2182448
0 голосов
/ 10 мая 2010

Я предпочитаю оператор по модулю по той простой причине, что он короче. И любая программа должна иметь возможность мечтать по модулю, поскольку она почти так же распространена, как оператор плюс.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...