Rapidité de lecture d'une variable - C#/.NET managed - Programmation
Marsh Posté le 14-04-2004 à 15:02:16
Comme Lenght est surement une "Property", elle va être évaluée à chaque itération.
La deuxième Méthode est donc la plus rapide.
en revanche cette méthode est déconseillée dans un environnement multi-threadé
Le cast n'a pas grand chose à voir la dedans (enfin je pense )
Marsh Posté le 14-04-2004 à 15:11:24
bah c'est pour ça que y a un truc qu'i s'appelle compilateur
pour un tableau dont la taille est constante, ça coute rien du tout. ce qui fait qu'entre le for, le for avec Length dans une variable et le foreach, je préfèrerais le foreach ou le for, le for avec constante n'étant d'aucune utilité
Marsh Posté le 14-04-2004 à 15:24:01
Taz a écrit : bah c'est pour ça que y a un truc qu'i s'appelle compilateur |
Effectivement le foreach est très élégant et très pratique mais il consomme beaucoup plus.
En ce qui concerne la question d'Imhotep je confirme mon point de vue : L'accès à une propriété en .NET est en fait un appel à une fonction (comme en COM) je pense donc que l'appel d'une fonction est toujours plus long que l'accès direct à une variable y compris quand la fonction est inline.
Marsh Posté le 14-04-2004 à 17:26:22
non, il ne consomme pas beaucoup plus.
un foreach sera dans beaucoup de cas la manière la plus rapide et permet au compilateur beaucoup d'optimisation.
sur un Array, le foreach égale à peu près le for, sur un ArrayList, il lui fou une claque monumentale
Marsh Posté le 14-04-2004 à 19:26:12
Si par exemple j'ai une propriété comme suit :
Code :
|
Est-ce qu'il va y avoir un appel de fonction (ralentir le programme ?) ou bien le compilateur va optimiser tout ça ?
Marsh Posté le 14-04-2004 à 20:30:53
le compilateur va pouvoir optimiser. regarder le msil pour en savoir plus. mais en aucun cas il ne faut faire de la parano, utiliser le foreach autant que possible
let set_Length je le sens mal là
Marsh Posté le 14-04-2004 à 20:52:34
Taz a écrit : le compilateur va pouvoir optimiser. regarder le msil pour en savoir plus. mais en aucun cas il ne faut faire de la parano, utiliser le foreach autant que possible |
Ok merci.
J'ai pas besoin du foreach dans ce cas là.
Citation : let set_Length je le sens mal là |
Pourquoi ?
Marsh Posté le 14-04-2004 à 20:56:45
Imhotep a écrit : |
pense pas comme ça. utilise le foreach puis le for si tu en as vraiment besoin
Imhotep a écrit :
|
euh il manque un peu de code ...
Marsh Posté le 14-04-2004 à 21:18:55
Taz a écrit : pense pas comme ça. utilise le foreach puis le for si tu en as vraiment besoin |
Ok
Taz a écrit : euh il manque un peu de code ... |
Je vois pas.... Ca marche très bien comme ça...
Marsh Posté le 14-04-2004 à 21:21:13
je sais bien, je veux juste dire que si fais ta propre Collection, this.length=value; ça redimensionnera sans doute pas grand chose
Marsh Posté le 14-04-2004 à 21:53:08
Taz a écrit : je sais bien, je veux juste dire que si fais ta propre Collection, this.length=value; ça redimensionnera sans doute pas grand chose |
ok
Mais c'est pas pour une collection En tout cas, merci pour tout ces conseils.
Marsh Posté le 15-04-2004 à 23:52:00
Taz a écrit : le compilateur va pouvoir optimiser. regarder le msil pour en savoir plus. mais en aucun cas il ne faut faire de la parano, utiliser le foreach autant que possible |
Pour le foreach je suis d'accord avec toi, pour les conteneurs complex Arraylist, ... c'est clair que c'est mieux!
En revanche pour la problème d'origine d'Imhotep, à savoir sortir le (...).Lengh de sa boucle, là je ne le suis pas!
Et pour en être certain, j'ai fait ce que tu as proposé:
j'ai compilé le petit pgm C# suivant :
Code :
|
bien sur en release avec les optimisations sur ON
Et j'ai DeMSILé (pardon pour le nom je ne savais pas quoi mettre ) voici ce que ça donne :
Code :
|
On peut facilement voire que pour la condition de sortie du test1 :
Code :
|
l'appel à get_Count ( qui correspond à la lecture de la propriété ) est effectué à chaque fois. Ce qui est d'ailleurs normal pour les environnements multi-thread.
Le compilateur n'a rien optimisé même si l'attribut [STAThread]était présent à la compilation.
C'est vrai aussi que ça ne va pas beaucoup changer les choses, mais par contre ça montre bien que les compilos ne font pas tout ...
Marsh Posté le 16-04-2004 à 00:03:14
certes : mais bon c'est minime, les compilateurs sont encore jeunes etc ...
mais bon de toutes façons tu donnes ici un bon contre-exemple vu que [] de ArrayList fait une vérification sur l'index
Marsh Posté le 16-04-2004 à 00:28:21
ce n'est pas un contre-exemple c juste pour montrer le problème de la variable dans le for
pour le for/foreach ça dépend plus des données et surtout du conteneur manipulés que d'autre chose, enfin à mon sens
De toute façon c'était sympa de fouiner ds le MSIL
Marsh Posté le 16-04-2004 à 03:13:23
enfin là tu voit bien qu'avec ArrayList l'utilisation du foreach serait nettement plus rapide
Marsh Posté le 16-04-2004 à 10:14:13
oui oui
j'aurais du prendre un bete tableau, pour l'exemple. Mais ArrayList ou autre chose ce n'est pas ce qui m'intéressait, j'en était toujours à la question de base et ne parlais que du for
Enfin j'espère qu'Imhotep va s'y retrouver dans tout ça
Marsh Posté le 16-04-2004 à 13:32:18
Oui je pense que je devrais pouvoir m'en sortir.
Par contre, j'ai essayé de remplacer for par foreach que cela était possible dans une classe utilisant un ArrayList, et c'est plus lent... Avec un for, le rendu d'une image pe prenait 36.12 sec en moyenne et avec un foreach, ca monte à 39.5 sec.
Avant :
Code :
|
Après :
Code :
|
Marsh Posté le 16-04-2004 à 13:33:06
enfin il faut surtout retenir que le foreach est une très bonne chose et que seuls les idiots paranos continueront à écrire du code sale blindé de for.
Marsh Posté le 17-04-2004 à 02:01:00
quelqu'un aurait une spécification complète du MSIL ?
ldloc.3
ldc.i4.1
add
stloc.3
pour un pauvre ++i c'est un peu long quand même ...
Marsh Posté le 19-04-2004 à 15:54:10
Taz a écrit : |
C'est toujours un peu pareil avec ces langages intermédières qui sont basés sur une "operand stack" (OS) :
ldloc.3 charge une variable sur l'OS
ldc.i4.1 charge la constante 1 sur l'OS
add ajoute les 2 éléments les plus hauts sur l'OS
stloc.3 sauvegarde la nouvelle valeur de l'OS dans la variable local correspondante
Marsh Posté le 19-04-2004 à 16:09:02
certes, j'ai pas dit le contraire, mais bon, prévoir un petit cas particulier, ça peut servir un peu dans même
Marsh Posté le 19-04-2004 à 16:33:44
Taz a écrit : certes, j'ai pas dit le contraire, mais bon, prévoir un petit cas particulier, ça peut servir un peu dans même |
De ce que j'ai pu voire, le gros des optimisations est fait lors de la compilation du MSIL vers le code natif, dans cet exemple la section
Code :
|
est transformé en un "bète"
Code :
|
la variable i étant constamment maintenu dans un registre.
Marsh Posté le 19-04-2004 à 16:50:27
ben j'espère bien que la compilation JIT travaille bien. cela dit... si tu utilises un interpréteur ou autre ...
Marsh Posté le 19-04-2004 à 16:55:05
C'est sure!
Je ne sais pas où en est mono:: mais en environnement M$ de toute façon tu passes par le JIT
Marsh Posté le 19-04-2004 à 16:56:33
mono aussi. seulement y a mint aussi, l'interpréteur. MS s'en fout, il bosse pour une seule architecture ... quand tu en as des dizaines à couvrir, c'est moins marrant ... donc mint est d'abord porté puis mono
Marsh Posté le 13-04-2004 à 20:35:29
Salut
J'avais une question simple concerant deux manière d'accéder à une variable.
La première manière est celle-ci :
((Ray)list[0]).length
Cette accès se fait plusieurs fois.
La deuxième manière est celle-ci :
double toto = ((Ray)list[0]).length; (créer une fois)
lire plusieurs fois toto.
Je me demandais si le fait de caster pouvait ralentir la vitesse de mon prgramme.
Merci
---------------
Qui avale une noix de coco fait confiance à son anus...