Не уверен, что если вы все еще ищете ответ, в любом случае:
вообще, нет никакой разницы в производительности между:
for (...) {
if (condition) continue;
some work;
}
и
for (...) {
if (!condition) some work;
}
Я предлагаю, чтобы избежать continue
, только потому, что он менее читабель, это в основном goto
.
Конечно, первое, что нужно оптимизировать, - это алгоритмы высокого уровня, структура данных и так далее. Если вы сделали это, и вам нужно максимизировать производительность - основным врагом является состояние/ветвь и неверные прогнозы. Есть много различных методов для этого:
- Move состояния вне цикла, если это возможно
- Split петли на нескольких из них
- Обычно умножение, деление и модуль довольно медленно, по сравнению с разрядными мудрыми операторами
- Некоторые условия могут быть заменены внеофисных заявления
- Un-Rool петли, чтобы минимизировать количество тестов
Мера каждое изменение
Например слегка измененный вариант кода для вычисления количества четных и нечетных чисел в диапазоне [-N, N], за исключением 0:
define('N', 100000000);
$start = microtime(true);
$odd_count = 0;
$even_count = 0;
for ($i=-N; $i<=N; $i++)
if ($i != 0)
if ($i % 2 != 0) $odd_count++;
else $even_count++;
$end = microtime(true);
echo 'odd: '.$odd_count."\n";
echo 'even: '.$even_count."\n";
echo 'time: '.($end-$start)."\n";
Конечно, мы можем заменить весь этот цикл с простой формулой (это алгоритм оптимизации высокого уровня), но позволяет попробовать работать с петлей:
Среднее время на моем хосте на нескольких трасс: 9,1 сек
Применить 1 го и 2-го правила:
for ($i=-N; $i<0; $i++)
if ($i % 2 != 0) $odd_count++;
else $even_count++;
for ($i=1; $i<=N; $i++)
if ($i % 2 != 0) $odd_count++;
else $even_count++;
Время: 7,7 сек
Применить 3-й и 4-й правило:
for ($i=-N; $i<0; $i++) {
$t = $i & 1;
$odd_count += $t;
$even_count += 1 - $t;
}
for ($i=1; $i<=N; $i++) {
$t = $i & 1;
$odd_count += $t;
$even_count += 1 - $t;
}
Время: 7,3 сек
И конечный результат:
for ($i=-N; $i<0;) {
$t = $i++ & 1; $odd_count += $t; $even_count += 1 - $t;
$t = $i++ & 1; $odd_count += $t; $even_count += 1 - $t;
$t = $i++ & 1; $odd_count += $t; $even_count += 1 - $t;
$t = $i++ & 1; $odd_count += $t; $even_count += 1 - $t;
}
for ($i=1; $i<=N;) {
$t = $i++ & 1; $odd_count += $t; $even_count += 1 - $t;
$t = $i++ & 1; $odd_count += $t; $even_count += 1 - $t;
$t = $i++ & 1; $odd_count += $t; $even_count += 1 - $t;
$t = $i++ & 1; $odd_count += $t; $even_count += 1 - $t;
}
Время: 7.0 сек.
Это будет очень небольшая разница, поэтому я предпочел бы сосредоточиться на оптимизации вещей, которые на самом деле имеют значение. Тем не менее, если вам просто нужны нечетные числа, вы можете сделать '$ i + 2' вместо' $ i ++ '. – Qirel
@Qirel Я знаю, что для математических циклов вроде '$ i + 2', но я делаю это как пример. Я думаю, когда вы работаете над реальными циклами с множеством данных, много циклов внутри цикла, как mutch будет быстрее и что? –
Собственно, то, что я написал неправильно, синтаксис: '$ i + = 2', а не' $ i + 2'. Хотя, если вы хотите проверить, какой из них быстрее, просто запустите тест. – Qirel