OVH Cloud OVH Cloud

For ... Each en partant de la fin ?

24 réponses
Avatar
Olivier
Bonjour


J'ai une collection trié
Peut-on faire une boucle avec un For Each mais en commencant par le dernier
?

Comme avant en faisant :
For i = mCol.Count - 1 To 0 Step -1



Merci
Olivier

4 réponses

1 2 3
Avatar
Simon Mourier [MS]
Cela dépend fortement code généré et donc du language (enfin, du
compilateur). Les compilateurs tels que C# ou VB.Net se débrouillent pour
que ca ne fasse que peut de différence. En général, tout dépend vraiment de
ce qu'on fait dans la boucle, de ce qui se cache derrière Count ou Length,
etc...

Une bonne méthode pour vérifier est de regarder l'IL qui est généré.

Qq liens:

Performance and Insight: For versus Foreach over a strongly typed array...
Some things you might not know.
http://weblogs.asp.net/justin_rogers/archive/2004/03/26/97230.aspx

Efficiency of iteration over arrays?
http://blogs.msdn.com/ericgu/archive/2004/04/18/115566.aspx

Array iteration performance
http://www.bluebytesoftware.com/blog/PermaLink.aspx?guida1cf7f-73f6-45a9-9aff-e88264b13b0e

Simon.

"Zazar" a écrit dans le message
de news: %23bjRGPA%
Bonsoir,

En considérant que pour une ArrayList le temps
d'énumération via une boucle For + la méthode Item est rigoureusement
identique au temps d'énumération via For Each (j'ai testé sur plusieurs
dizaines de milliers d'éléments),



C'est pas de chance, il aurait fallu tester sur peu d'éléments ou sur
beaucoup plus d'élements pour pouvoir constater la différence.
En gros :
foreach crée un objet => 1 création d'objet par boucle : sur beaucoup
d'éléments ça ne se voit pas.
A chaque itération, avec foreach il y a quelques petites comparaisons qui
sont faîtes : elles sont peu gourmandes et il faut donc plus que quelques
dizaines de milliers d'éléments pour constater une différence.
Le temps d'énumération en utilisant une boucle for est donc moins grand
qu'en utilisant une boucle foreach, même si ça n'a pas toujours un impact
significatif.


--
Zazar




Avatar
Simon Mourier [MS]
Et j'oubliais le lien plus important (définitif :-)
http://blogs.msdn.com/brada/archive/2004/04/29/123105.aspx

Qui montre qu'avec C# c'est identique (pour des arrays)
Simon.

"Simon Mourier [MS]" a écrit dans le message
de news: Op9XMCD%
Cela dépend fortement code généré et donc du language (enfin, du
compilateur). Les compilateurs tels que C# ou VB.Net se débrouillent pour
que ca ne fasse que peut de différence. En général, tout dépend vraiment
de ce qu'on fait dans la boucle, de ce qui se cache derrière Count ou
Length, etc...

Une bonne méthode pour vérifier est de regarder l'IL qui est généré.

Qq liens:

Performance and Insight: For versus Foreach over a strongly typed array...
Some things you might not know.
http://weblogs.asp.net/justin_rogers/archive/2004/03/26/97230.aspx

Efficiency of iteration over arrays?
http://blogs.msdn.com/ericgu/archive/2004/04/18/115566.aspx

Array iteration performance
http://www.bluebytesoftware.com/blog/PermaLink.aspx?guida1cf7f-73f6-45a9-9aff-e88264b13b0e

Simon.

"Zazar" a écrit dans le
message de news: %23bjRGPA%
Bonsoir,

En considérant que pour une ArrayList le temps
d'énumération via une boucle For + la méthode Item est rigoureusement
identique au temps d'énumération via For Each (j'ai testé sur plusieurs
dizaines de milliers d'éléments),



C'est pas de chance, il aurait fallu tester sur peu d'éléments ou sur
beaucoup plus d'élements pour pouvoir constater la différence.
En gros :
foreach crée un objet => 1 création d'objet par boucle : sur beaucoup
d'éléments ça ne se voit pas.
A chaque itération, avec foreach il y a quelques petites comparaisons qui
sont faîtes : elles sont peu gourmandes et il faut donc plus que quelques
dizaines de milliers d'éléments pour constater une différence.
Le temps d'énumération en utilisant une boucle for est donc moins grand
qu'en utilisant une boucle foreach, même si ça n'a pas toujours un impact
significatif.


--
Zazar








Avatar
Zazar
Bonjour,

Cela dépend fortement code généré et donc du language (enfin, du
compilateur). Les compilateurs tels que C# ou VB.Net se débrouillent pour
que ca ne fasse que peut de différence. En général, tout dépend vraiment
de
ce qu'on fait dans la boucle, de ce qui se cache derrière Count ou Length,
etc...




Vous parlez des Array, alors que je parlais des ArrayList. C'est une
situation différente :

Tous les tableaux sont des types particuliers au comportement bien défini,
les compilateurs peuvent se permettre de faire des optimisations : le
compilateur C# par exemple transforme purement et simplement les boucles
foreach sur les tableaux en boucle for.

Le cas des ArrayList est différent : c'est juste une collection implémentant
IEnumerable; le compilateur ne peut pas faire la transformation. En effet si
d'aprés la documentation, le parcours selon une boucle foreach et une boucle
for doivent avoir la même sémantique, rien n'oblige le programmeur à
respecter la documentation et le compilateur ne peut pas faire l'assertion
que le programmeur l'ait respecté. L'exécution d'une boucle foreach passe
donc obligatoirement par l'appel à GetEnumerator et les appels aux méthodes
MoveNext et Current de l'énumérateur. Aprés, le JIT pourrait regarder "ce
qui se passe", voir que tout ce code n'a pour but que de faire une boucle
for et qu'il n'y a pas d'effet de bord significatif sur le programme, mais
c'est loin d'être trivial.

--

Zazar
Avatar
Thierry Bertrand
Ok, je comprend mieux car je dois avouer que je ne comprennais pas le sens
de ta question.

Autrement dit tu voudrais pouvoir écrire "for each previous elem in list" au
lieu de "for i=n to 0 step -1", voir du "do ... i=i-1 loop" (que je trouve
très beau) -> demande officielle d'ajout dans la syntaxe

Ne serait-ce pas de l'estétisme poussé à outrance ??? ;-))))
Dans ce cas je préfère le do ... loop qui est vraiment hyper beau ;-)

Alors à mon avis le mieux est de continuer comme ça, car même si des
pouiemes de quart de nano secondes sont consommés en plus ou en moins entre
le for i=1 et le for each, voir avec le do ... loop et l' autodécrément, ce
sera plus rapide que re-trier ta liste en sens inverse et de la reparcourir,
surtout qu'il faudra sans doute que tu la re-re-tries après car si tu a une
liste triée dans un sens, c'est que c'est comme cela que tu la veux dans la
plupart des cas.

Perso, maintenant, je pars du principe que l'optimisation des pouièmes est
passée de mode, sauf traitement particulièrement lourd.
Après reste la beauté du source.

Moi je vote pour les "do ... loop" beaucoup plus beaux que les "For ...
next"



"Olivier" <aa.aa.aa> a écrit dans le message de news:
uu29ew$
;-)


C'est exactement ce que je fais actuellement. Faute de mieux, avant


d'avoir
ces excellentes discussions.
Ma question était certe un peu incomplete.
J'ai oublié de rajouter les mots :

"... actuellement je fais For i = Col.Count-1 To 0 Step -1 ....
comment faire la même chose avec un For Each..."

Merci à tous.

Olivier


"Thierry Bertrand" <bertrand.thierry(nospam)@(nospam)numericable.fr> a


écrit
dans le message de news:%239KPZK%
> Comprends pas ???
>
> Tu demandes à parcourir un for each mais en sens inverse.
> cela est strictement équivalent à prendre les éléments de ta collection
> dans une boucle en les adressant directement par un index décroissant.
>
> Où alors ton problème n'est pas contenu dans ta question.
>
>
>
> "Olivier" <aa.aa.aa> a écrit dans le message de news:
>
> > oui, mais c'est pas vraiment mon pb :-)
> >
> > Merci
> > Olivier
> >
> >
> > "Thierry Bertrand" <bertrand.thierry(nospam)@(nospam)numericable.fr> a
> écrit
> > dans le message de news:
> > > C'est bizarre, mais j'avais appris qu'une boucle for peut toujours
être
> > > transformée en une boucle do while
> > >
> > > For i= mCol.Count - 1 to 0 step -1
> > >
> > > se tranforme simplement en
> > >
> > > I=mCol.Count-1
> > > do while i >=0
> > > ...
> > > i=i-1
> > > loop
> > >
> > > me gourre-je ???
> > >
> > >
> > > "Olivier" <aa.aa.aa> a écrit dans le message de news:
> > >
> > > > Bonjour
> > > >
> > > >
> > > > J'ai une collection trié
> > > > Peut-on faire une boucle avec un For Each mais en commencant par


le
> > > dernier
> > > > ?
> > > >
> > > > Comme avant en faisant :
> > > > For i = mCol.Count - 1 To 0 Step -1
> > > >
> > > >
> > > >
> > > > Merci
> > > > Olivier
> > > >
> > > >
> > >
> > >
> >
> >
>
>




1 2 3