Какая конструкция предпочтительнее и почему?
A:
if(i < 1023)
++i;
else
i = 0;
B:
++i;
if(i == 1024)
i = 0;
C:
i = (i + 1) & 1023;
или другой?
Мне нравится альтернатива C, потому что она небольшая и не имеет ветвей (таким образом, нет разрыва конвейера), но она выполняет операцию AND, которая полезна только в 1 из каждых 1024 раз …
Я бы выбрал вариант С каждый раз. Это может быть менее очевидно сразу, но идиома достаточно понятна для любого, кто имеет опыт программирования, и это спасает вас от этой условной ветви. На современных (то есть что-нибудь легко за последние 10 лет) суперскалярных процессорах узким местом является предсказание памяти и / или ветвлений; арифметические операции типа двоичного И, в хорошем приближении, бесплатны.
Запуск их в цикле 100k for дает мне следующие результаты:
A: 10,439 с
B: 9,845 с
С: 9,482 сек.
Лично я бы использовал A, потому что я привык к такому типу обозначений, и он остается ясным. Если скорость — проблема, C, кажется, лучший из этих трех.