В чем разница между ++$iи $i++в PHP?
Ответы:
++$iявляется предварительным приращением, а $i++пост-приращением.
iсначала увеличивает переменную, а затем отменяет ссылку.i"Воспользуйтесь тем фактом, что PHP позволяет выполнять пост-инкремент ($ i ++) и пре-инкремент (++ $ i). Смысл остается таким же, пока вы не пишете ничего вроде $ j = $ i ++, однако предварительное увеличение происходит почти на 10% быстрее, а это означает, что вам следует переключаться с пост-инкремента на предварительное увеличение, когда у вас есть возможность, особенно в узких циклах и особенно если вы педантичны в отношении микрооптимизации! " - TuxRadar
Для дальнейшего пояснения, пост-инкремент в PHP был задокументирован как хранение временной переменной, которая относится к этим 10% накладным расходам по сравнению с предварительным инкрементом.
++$iувеличивается $i, но оценивается как значение $i+1
$i++приращения $i, но оценивается как старое значение $i.
Вот пример:
$i = 10;
$a = $i++;
// Now $a is 10, and $i is 11
$i = 10;
$a = ++$i;
// Now $a is 11, and $i is 11
Иногда требуется небольшая предварительная стоимость использования $i++. Смотрите, когда вы делаете что-то вроде
$a = $i++;
Вы действительно делаете это:
$temporary_variable = $i;
$i=$i+1;
$a=$temporary_variable;
$a=func()++и спросите себя, как вы могли бы переписать его без ++ и без вызова func () более одного раза.
++$i //first increment $i then run line
$i++ //first run line then increment $i
в этом случае разницы нет:
for($i = 0;$i<3;++$i)var_dump $i;
/*
int(0)
int(1)
int(2)
*/
for($i = 0;$i<3;$i++)var_dump $i;
/*
int(0)
int(1)
int(2)
*/
но:
for($i = 0;$i<3; $j = ++$i )var_dump($j);
/*
NULL
int(1)
int(2)
*/
for($i = 0;$i<3; $j = $i++ )var_dump($j);
/*
NULL
int(0)
int(1)
*/
в этом примере просто
<?php
$x = 10;
echo $x++. ' '.$x; // the result is 10 and 11
echo '<br>';
$y = 10;
echo ++$y. ' ' .$y; // the result is 11 and 11
// so the $x++ is not showing +1 at first but the next time
// and the ++y is showing +1 first time but not increasing next
Разница в том, ++$iчто $iпеременная будет увеличиваться и возвращать обновленное значение, тогда как $i++вернет исходное значение, поэтому увеличивайте его.
$prefix = 1;
$postfix = 1;
echo ++$prefix; // 2
echo $postfix++; // 1
Другой способ взглянуть на приращение до и после приращения - это сокращение для объединения двух операторов.
Предварительное приращение
// long form
$y = $y + 1;
$x = $y; // any statement using $y
// shorthand
$x = ++$y; // the same statement using $y
Пост-инкремент
// long form
$x = $y; // any statement using $y
$y = $y + 1;
// shorthand
$x = $y++; // the same statement using $y
$ i ++ известен как постинкремент. Он увеличивает значение $ i только после того, как сначала присваивает исходное значение $ i переменной $ j.
++ $ i называется предварительным приращением. Он увеличивает значение $ i перед присвоением значения $ j, поэтому обновленное значение $ i будет присвоено $ j.
Следовательно,
$i = 4;
$j = $i++;
// Now, $i = 5 and $j = 4
$i = 4;
$j = ++$i;
// Now, $i = 5 and $j = 5
Эти теории аналогичным образом применимы и к декременту.
Надеюсь это поможет!
Наверное, лучше всего это проиллюстрировать на примере ...
Пост-инкремент:
$zero = 0;
$n = $zero++; //$n is zero
Предварительное приращение:
$zero = 0;
$n = ++$zero; //$n is one
Краткий ответ:
Длинный ответ: если вы немного подумаете, как бы вы реализовали это самостоятельно, вы, вероятно, поймете, почему префикс быстрее. По правде говоря, постфикс фактически (часто) реализуется с использованием префикса:
const T T::operator ++ (int) // postfix
{
T orig(*this);
++(*this); // call prefix operator
return (orig);
}
Избегайте постфикса, если у вас нет особой причины этого не делать. Разница в скорости может быть довольно большой для сложных типов данных.
Я действительно посмотрел это несколько дней назад. Вот мой источник.
Основное назначение оператора приращения после исправления - это использование следующего вида:
while(*condition*)
$array[$i++] = $something;
Это очень элегантный способ обойти некоторые итерации массива. Сломать:
Во всех остальных случаях следует использовать префиксный оператор. Это делает код более понятным (вы можете быть уверены, что уже работаете с увеличенным значением конкретной переменной).
Я запустил следующий код, чтобы проверить, работает ли ++ $ i на 10% быстрее, чем $ i ++. Я признаю, что код не дает стабильного результата, но даже тогда я должен был хотя бы увидеть некоторые цифры около 10%. Наивысший результат был примерно 4-4,5%.
<?php
$randomFloat = rand(0, 10) / 10;
$before1 = microtime(true);
for($i=0; $i <1000000; ++$i){
$rand = (rand(0, 10) / 10) * (rand(0, 10) / 10);
}
$after1 = microtime(true);
echo 'it took '.($after1-$before1) . ' seconds fot ++$i<br />';
$before2 = microtime(true);
for($i=0; $i <1000000; $i++){
$rand = (rand(0, 10) / 10) * (rand(0, 10) / 10);
}
$after2 = microtime(true);
echo 'it took '.($after2-$before2) . ' seconds fot $i++<br /><br />';
echo '++$i is '.((($after1-$before1)*100)/($after2-$before2)-100).'% faster than $i++';
Оба оператора по-прежнему выполняют то, что подразумевает их синтаксис: увеличивают. Независимо от префикса или постфикса, переменная обязательно будет увеличена на 1. Разница между ними заключается в их возвращаемых значениях.
1. Приращение префикса возвращает значение переменной после того, как оно было увеличено.
2. С другой стороны, более часто используемый постфиксный инкремент возвращает значение переменной до того, как оно было увеличено.
// Prefix increment
let prefix = 1;
console.log(++prefix); // 2
console.log(prefix); // 2
// Postfix increment
let postfix = 1;
console.log(postfix++); // 1
console.log(postfix); // 2
Чтобы запомнить это правило , я думаю о синтаксисе этих двух. Когда вводят приращение префикса, он говорит ++ x. Здесь важна позиция ++. Сказать ++ x означает сначала увеличить (++), а затем вернуть значение x, таким образом, мы имеем ++ x. Постфиксное приращение работает наоборот. Сказать x ++ означает сначала вернуть значение x, а затем увеличить его (++), таким образом, x ++.