while conditie met array?

Overzicht Reageren

Sponsored by: Vacatures door Monsterboard

Pagina: « vorige 1 2

Ozzie PHP

Ozzie PHP

25/06/2014 14:47:42
Quote Anchor link
@SanThe. Nee, zoals Erwin het doet klopt het. Dat was wat ik bedoelde.

Ben alleen wel benieuwd waarom ++$i ipv $i++ ?
Gewijzigd op 25/06/2014 14:48:20 door Ozzie PHP
 
PHP hulp

PHP hulp

29/04/2024 06:48:26
 
Gerhard l

gerhard l

25/06/2014 14:53:05
Quote Anchor link
Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
4
5
6
7
8
9
<?
$i
= 1;
echo ++$i; # 2
echo $i; #2

$j = 1;
echo $j++; #1
echo $j; #2
?>


Oftewel de plusjes voor de variabelen worden eerst uitgevoerd voor het echoen.
Gewijzigd op 25/06/2014 14:54:04 door gerhard l
 
Ozzie PHP

Ozzie PHP

25/06/2014 14:56:25
Quote Anchor link
Ah zo, thanks. En bij het ophogen van een iterator, zoals in het voorbeeld van Erwin, wat is dan het voordeel van ++$i versus $i++ ? Of maakt het in dat geval niks uit?
 
Gerhard l

gerhard l

25/06/2014 15:01:07
Quote Anchor link
Ik denk niet dat het veel uitmaakt, maar volgens deze test, is ++$i sneller/minder geheugen als $i++ als het alleen voor ophogen dient.
 
Ozzie PHP

Ozzie PHP

25/06/2014 15:08:39
Quote Anchor link
Dankjewel gerhard. Ik heb even een benchmark gedaan en de ++$i variant is inderdaad wat sneller!
 
Willem vp

Willem vp

26/06/2014 17:42:17
Quote Anchor link
Over snelheid gesproken: aangezien PHP feitelijk gezien geen arrays kent, is foreach($array) aanmerkelijk sneller dan while($array[$i]). Dat kun je niet compenseren met je ++$i. ;-)
 
Ozzie PHP

Ozzie PHP

26/06/2014 17:53:28
Quote Anchor link
>> aangezien PHP feitelijk gezien geen arrays kent

Wat bedoel je daarmee Willem?
 
Willem vp

Willem vp

26/06/2014 18:14:34
Quote Anchor link
Een array is een datastructuur waarbij elk element een vaste, berekenbare, offset heeft vanaf het begin van het eerste element.

Stel je hebt een array van 10 integers en een integer is 4 bytes. Om het eerste element $array[0] te vinden neem je dan het beginadres van de datastructuur en telt er 0x4 bytes bij op. Het zevende element is dus te vinden op 6x4 bytes vanaf het begin.

In PHP is een array eigenlijk een linked list. Als je een element toevoegt aan de array, zal in het laatste element een pointer worden opgenomen naar het nieuwe element. Als je $array[3] wilt hebben, begint PHP te zoeken bij het eerste element van de array. Hij vergelijkt de array key met de key die jij zoekt, en als die niet overeenkomen, gaat hij via de pointer naar het volgende element. Zo zoekt hij net zolang tot hij de juiste key gevonden heeft.

Het gevolg hiervan is dat wanneer je een array afloopt met while($array[$i]){$i++;} de tijd die je while-loop nodig heeft kwadratisch (!) toeneemt met het aantal elementen in je array. Een foreach-loop heeft in dit geval een lineair verband.
 
Wouter J

Wouter J

26/06/2014 18:24:41
Quote Anchor link
Overigens zijn in dit topic de while loop oplossingen en de foreach oplossing gegeven door Ozzie compleet anders.
While *stopt* wanneer er geen element meer met color is, foreach zou hem gewoon *overslaan*. Om de while loop goed te kunnen gebruiken zou er dus een break in de else statement moeten. Ik weet niet of Ozzie dat wil.

Ook kun je beter een pointer (current, next) gebruiken voor de iteratie dan een tellertje. De pointer is niet afhankelijk van de key (text, int, etc.), terwijl een tellertje dat wel is. en voor de puristen is een tellertje ook plainfout, aangezien keys in PHP alleen maar strings zijn, omdat alle arrays in PHP hashtables zijn)

Als laatste snap ik niet waarom je niet "gewoon een foreach loop" gebruikt? Gebruik features waarvoor ze gemaakt zijn en ga dan niet met andere dingen stoeien.
Gewijzigd op 26/06/2014 18:25:24 door Wouter J
 
Willem vp

Willem vp

26/06/2014 20:19:30
Quote Anchor link
> omdat alle arrays in PHP hashtables zijn

En eigenlijk klopt dat ook niet helemaal, omdat je bij een hashtable niet zelf de volgorde van de elementen kunt bepalen. Bij PHP kan dat wel, omdat er een chained/linked hashtable gebruikt wordt.
 
Ozzie PHP

Ozzie PHP

26/06/2014 20:46:17
Quote Anchor link
>> Zo zoekt hij net zolang tot hij de juiste key gevonden heeft.

Tot zover kan ik je prima volgen...

>> Het gevolg hiervan is dat wanneer je een array afloopt met while($array[$i]){$i++;} de tijd die je while-loop nodig heeft kwadratisch (!) toeneemt met het aantal elementen in je array. Een foreach-loop heeft in dit geval een lineair verband.

Say whhhhaaaat?? :-)

Bedoel je dat die $i telkens "gezocht" moet worden, terwijl in de for-each gewoon naar het volgende element wordt gesprongen?

>> Om de while loop goed te kunnen gebruiken zou er dus een break in de else statement moeten. Ik weet niet of Ozzie dat wil.

Ja, het is of een while-loop, of een foreach met een break in de else. Beiden komt op hetzelfde neer. Dus in dat geval kan ik beter de snellere foreach variant gebruiken.

>> Als laatste snap ik niet waarom je niet "gewoon een foreach loop" gebruikt? Gebruik features waarvoor ze gemaakt zijn en ga dan niet met andere dingen stoeien.

Dat zal ik je uitleggen Wouter. Ik dacht namelijk dat een while juist bedoeld was om iets te doen "zolang een bepaalde expressie geldig is". Dus ik dacht "zolang die color geset is", doe iets... Ik dacht dat dat dan juist wel een goede reden zou zijn om while te gebruiken. Maar heb ik dat dan verkeerd begrepen?

Toevoeging op 26/06/2014 21:09:31:

EXTRA OPMERKING

Ik heb even een benchmark gedaan, en wat blijkt... de while-loop is toch ietsje (niet veel) sneller. Ik denk dat het komt omdat de betreffende array een numerieke array is waarbij de getallen in de juiste volgorde staan. Dus hij beging met key 0 en loopt dan op naar boven. Zou dat de reden zijn waarom de while-loop toch sneller gaat?
Gewijzigd op 26/06/2014 20:47:25 door Ozzie PHP
 
Willem vp

Willem vp

27/06/2014 00:27:15
Quote Anchor link
> Bedoel je dat die $i telkens "gezocht" moet worden, terwijl in de for-each gewoon naar het volgende element wordt gesprongen?

Ja, dat bedoelde ik. Wat overigens niet waar blijkt te zijn. ;-) Ik had ergens in mijn achterhoofd zitten dat arrays geïmplementeerd zijn als linked lists, maar het zijn dus ordered hashtables. Dat is stukken beter, maar nog wel steeds een klein beetje langzamer dan echte arrays (maar het geeft wel wat meer flexibiliteit, omdat je ook niet-numerieke keys kunt gebruiken).

> Ja, het is of een while-loop, of een foreach met een break in de else.

Geen else nodig:
Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
4
5
6
<?php
foreach ($foo as $element) {
  if (!isset($element['color'])) { break; }
  # Doe iets
}
?>


> Ik dacht namelijk dat een while juist bedoeld was om iets te doen "zolang een bepaalde expressie geldig is".

Dat klopt. Maar in jouw geval heb je steeds een andere expressie: de eerste keer $foo[0]['color'], daarna $foo[1]['color'], etc. Daardoor moet je in je while-loop dus wat extra logica inbouwen om door je array heen te itereren, waardoor een foreach al snel een beter mechanisme is om je doel te bereiken.

> Ik heb even een benchmark gedaan, en wat blijkt... de while-loop is toch ietsje (niet veel) sneller.

Uiteraard heb ik dat ook meteen maar even getest ;-) en bij mij is de while consequent zo'n 25% langzamer. Zou het kunnen dat je in je while geen "$val = $foo[$i]" hebt gedaan? In dat geval is je while-loop namelijk wel sneller, maar functioneel niet gelijk aan de foreach.

En om mijn uitspraak uit mijn eerdere post meteen te ontkrachten: de tijdsduur van de while neemt (gelukkig) niet kwadratisch toe met het aantal elementen. Overigens heeft PHP enkele array-functies waarbij dat wel het geval is (in_array() bijvoorbeeld).

> Ik denk dat het komt omdat de betreffende array een numerieke array is waarbij de getallen in de juiste volgorde staan. Dus hij begint met key 0 en loopt dan op naar boven. Zou dat de reden zijn waarom de while-loop toch sneller gaat?

Nee. Ik heb het ook met een niet-geordende array geprobeerd en dat maakt geen verschil. Even voor de volledigheid: het feit dat (in PHP) een array numerieke keys heeft, wil niet zeggen dat de elementen in numerieke volgorde staan. Ze staan altijd in de volgorde waarin je ze aan de array hebt toegevoegd:
Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
4
5
6
7
8
9
10
<?php
$x
= [];
$x[0] = 'a';
$x[2] = 'b';
$x[1] = 'c';
foreach ($x as $y => $z) { echo "$y - $z\n"; }
0 - a
2 - b
1 - c
?>

In elke andere taal -die ik ken- zou dat lijstje 0/1/2 als volgorde hebben gehad.
Gewijzigd op 27/06/2014 00:35:39 door Willem vp
 
Ozzie PHP

Ozzie PHP

27/06/2014 00:35:04
Quote Anchor link
>> Geen else nodig:

Dat zou ook inderdaad kunnen.

>> Uiteraard heb ik dat ook meteen maar even getest ;-) en bij mij is de while consequent zo'n 25% langzamer.

>> Zou het kunnen dat je in je while geen "$val = $foo[$i]" hebt gedaan?

Wat bedoel je hiermee?

Ik doe (ongeveer) dit:

Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
4
5
6
7
<?php
$i
= 0;
while(isset($foo[$i]['color']) && $foo[$i]['color'] === $bar) {
    // doe iets
    ++i;
}

?>

En dat is sneller dan:

Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
4
5
6
7
8
9
<?php
foreach ($foo as $value) {
    if (isset($value['color']) && $value['color'] === $bar) {
        // doe iets
    } else {
        break;
    }
}

?>

De while-loop wint het van de foreach-loop bij mij.
Gewijzigd op 27/06/2014 00:36:05 door Ozzie PHP
 
Willem vp

Willem vp

27/06/2014 00:42:34
Quote Anchor link
Je zit appels met pannekoeken te vergelijken. Waar komt die $i in de foreach ineens vandaan? Waarschijnlijk nog uit de while-loop, en die staat daar dus op de waarde van de hoogste key. Geen wonder dat de foreach langzamer is.
(grr... je code aanpassen terwijl ik een reactie zit te schrijven... het zou verboden moeten worden! ;-) )

Maar eigenlijk bedoelde ik dit:
Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
4
5
6
7
8
<?php
$i
= 0;
while(isset($foo[$i]['color']) && $foo[$i]['color'] === $bar) {
    $value = $foo[$i];
    // doe iets
    ++i;
}

?>


De foreach kent namelijk de waarde van $foo[$i] toe aan $value. Als je dat in je while-loop niet doet, is hij dus functioneel niet hetzelfde en test je ook twee verschillende dingen.
Gewijzigd op 27/06/2014 00:46:26 door Willem vp
 
Ozzie PHP

Ozzie PHP

27/06/2014 00:45:05
Quote Anchor link
>> Je zit appels met pannekoeken te vergelijken. Waar komt die $i in de foreach ineens vandaan? Waarschijnlijk nog uit de while-loop, en die staat daar dus op de waarde van de hoogste key. Geen wonder dat de foreach langzamer is.

Lol... die had ik verkeerd gekopieerd, maar je had m'n edit waars. nog niet gezien :)

In de while gebruik ik gewoon direct $foo[$i]['color'] ipv $foo eerst aan een value toe te kennen.
Gewijzigd op 27/06/2014 00:46:07 door Ozzie PHP
 

Pagina: « vorige 1 2



Overzicht Reageren

 
 

Om de gebruiksvriendelijkheid van onze website en diensten te optimaliseren maken wij gebruik van cookies. Deze cookies gebruiken wij voor functionaliteiten, analytische gegevens en marketing doeleinden. U vindt meer informatie in onze privacy statement.