Jaka jest różnica między ++$i
i $i++
w PHP?
Odpowiedzi:
++$i
jest preinkrementacja, podczas gdy $i++
post-inkrementacja.
i
najpierw inkrementuj zmienną, a następnie usuwaj referencje.i
„Skorzystaj z faktu, że PHP umożliwia post-inkrementację ($ i ++) i preinkrementację (++ $ i). Znaczenie jest takie samo, o ile nie piszesz czegoś takiego jak $ j = $ i ++ preinkrementacja jest prawie 10% szybsza, co oznacza, że powinieneś przełączyć się z post-inkrementacji na preinkrementację, kiedy masz taką możliwość, zwłaszcza w ciasnych pętlach, a zwłaszcza jeśli pedantycznie podchodzisz do mikro-optymalizacji! ” - TuxRadar
Dla dalszego wyjaśnienia, post-inkrementacja w PHP została udokumentowana jako przechowywanie tymczasowej zmiennej, która przypisuje to 10% narzut w porównaniu z preinkrementacją.
++$i
zwiększa $i
, ale szacuje do wartości $i+1
$i++
przyrostów $i
, ale oblicza do starej wartości $i
.
Oto przykład:
$i = 10;
$a = $i++;
// Now $a is 10, and $i is 11
$i = 10;
$a = ++$i;
// Now $a is 11, and $i is 11
Czasami istnieje niewielki koszt wykonania $i++
. Widzisz, kiedy robisz coś takiego
$a = $i++;
Naprawdę to robisz:
$temporary_variable = $i;
$i=$i+1;
$a=$temporary_variable;
$a=func()++
i zadaj sobie pytanie, jak można by to przepisać bez ++ i bez wywoływania func () więcej niż raz.
++$i //first increment $i then run line
$i++ //first run line then increment $i
w tym przypadku nie ma różnicy:
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)
*/
ale:
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)
*/
ten przykład elplains jest prosty
<?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
Różnica jest następująca: ++$i
zwiększy $i
zmienną i zwróci zaktualizowaną wartość, podczas gdy $i++
zwróci oryginalną wartość, więc ją zwiększy.
$prefix = 1;
$postfix = 1;
echo ++$prefix; // 2
echo $postfix++; // 1
Innym sposobem spojrzenia na inkrementację przed i po jest to, że jest to skrót łączący 2 stwierdzenia.
Wstępne zwiększanie
// long form
$y = $y + 1;
$x = $y; // any statement using $y
// shorthand
$x = ++$y; // the same statement using $y
Postinkrementacja
// long form
$x = $y; // any statement using $y
$y = $y + 1;
// shorthand
$x = $y++; // the same statement using $y
$ i ++ jest znane jako post-inkrementacja. Zwiększa wartość $ i dopiero po przypisaniu pierwotnej wartości $ i do $ j.
++ $ i jest znane jako preinkrementacja. Zwiększa wartość $ i przed przypisaniem wartości do $ j, więc zaktualizowana wartość $ i zostanie przypisana do $ j.
W związku z tym,
$i = 4;
$j = $i++;
// Now, $i = 5 and $j = 4
$i = 4;
$j = ++$i;
// Now, $i = 5 and $j = 5
Teorie te stosują się w podobny sposób również do dekrementacji.
Mam nadzieję że to pomoże!
Najlepiej ilustruje to przykład ...
Post-inkrementacja:
$zero = 0;
$n = $zero++; //$n is zero
Pre-inkrementacja:
$zero = 0;
$n = ++$zero; //$n is one
Krótka odpowiedź:
Długa odpowiedź: Jeśli się trochę nad tym zastanowisz, jak sam byś je zaimplementował, prawdopodobnie zdasz sobie sprawę, dlaczego prefiks jest szybszy. Prawdę mówiąc, postfix jest faktycznie (często) implementowany przy użyciu przedrostka:
const T T::operator ++ (int) // postfix
{
T orig(*this);
++(*this); // call prefix operator
return (orig);
}
Unikaj Postfix, chyba że masz konkretny powód, aby tego nie robić. W przypadku złożonych typów danych różnica w szybkości może być dość duża.
Sprawdziłem to kilka dni temu. Oto moje źródło.
Głównym celem operatora inkrementacji po naprawie jest użycie w następujący sposób:
while(*condition*)
$array[$i++] = $something;
Jest to bardzo elegancki sposób na obejście niektórych iteracji tablic. Awaria:
We wszystkich innych przypadkach należy użyć operatora prefiksu. Dzięki temu kod jest dużo bardziej przejrzysty (możesz być pewien, że już pracujesz z inkrementowaną wartością danej zmiennej).
Uruchomiłem następujący kod, aby sprawdzić, czy ++ $ i jest o 10% szybsze niż $ i ++. Przyznaję, kod nie ma stabilnego wyniku, ale nawet wtedy powinienem był przynajmniej zobaczyć kilka liczb w pobliżu 10%. Najwyższy, jaki uzyskałem, wynosił około 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++';
Oba operatory nadal robią to, co implikuje ich składnia: zwiększać. Niezależnie od przedrostka lub przyrostka, zmienna z pewnością zostanie zwiększona o 1. Różnica między nimi polega na ich wartościach zwracanych.
1. Przyrost przedrostka zwraca wartość zmiennej po jej zwiększeniu.
2. Z drugiej strony, częściej stosowany przyrost przyrostka zwraca wartość zmiennej, zanim została zwiększona.
// 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
Aby zapamiętać tę regułę , myślę o składni tych dwóch. Kiedy wpisuje się przyrost prefiksu, mówi się ++ x. Ważna jest tutaj pozycja ++. Powiedzenie ++ x oznacza najpierw inkrementację (++), a następnie zwrócenie wartości x, więc mamy ++ x. Przyrost przyrostka działa odwrotnie. Powiedzenie x ++ oznacza najpierw zwrócenie wartości x, a następnie zwiększenie (++) jej, a więc x ++.