Если у меня есть стандарт для цикла, есть ли более эффективный способ пропустить определенные вхождения?
Например:
A:
for (int i = 0; i < n; i++)
{
if (i != n / 2 && i != n / 3 && i != n / 4)
{
val += DoWork(i);
}
else
{
continue;
}
}
B
for (int i = 0; i < n / 4; i++)
{
val += DoWork(i); ;
}
for (int i = n / 4 + 1; i < n / 3; i++)
{
val += DoWork(i);
}
for (int i = n / 3 + 1; i < n / 2; i++)
{
val += DoWork(i);
}
for (int i = n / 2 + 1; i < n; i++)
{
val += DoWork(i);
}
С:
for (int i = 0; i < n; i++)
{
if (i == n / 2 || i == n / 3 || i == n / 4)
{
continue;
}
else
{
val += DoWork(i);
}
}
Для n = int.MaxValue
результаты были следующими:
A Результаты: 57498 миллисекунд.
B Результаты: 42204 миллисекунды.
C Результаты: 57643 миллисекунды.
РЕДАКТИРОВАТЬ НА ОСНОВЕ ОТВЕТА ЧЕРКА.
Я добавил еще один метод теста D следующим образом:
D
for (int i = 0; i < n; i = (i != n / 2 -1 && i != n / 3 -1 && i != n / 4-1) ? i+1: i+2)
{
val += DoWork(i);
}
и получил следующие результаты:
A Результаты: 56355 миллисекунд.
Результаты B: 40612 миллисекунд.
C Результаты: 56214 миллисекунды.
D Результаты: 51810 миллисекунд.
Edit2: после предварительного вычисления значений для n / 2 n / 3 и n / 4 вне цикла получим:
A Результаты: 50873 миллисекунд.
Результаты B: 39514 миллисекунд.
C Результаты: 51167 миллисекунд.
D Результаты: 42808 миллисекунд.
Кажется, что петля D снова близка к «разворачиванию» B, а A и C все еще занимают значительно больше времени.
Что касается того, что я ожидал, что касается сравнений между каждым из методов.
Мой вопрос: есть ли более эффективный способ сделать это?