Lorsque vous utilisez Ce que je veux vraiment savoir, c'est si la réglage d'une variable locale à la longueur de la dimension d'un tableau ajouterait toute efficacité si elle est utilisée à l'intérieur d'une grande boucle ou si je peux simplement appeler Array.getlength () sur et sur w / o toute pénalité de vitesse. P> array.getlength (dimension) code> in c #, la taille de la matrice est-elle en fait calculée chaque fois qu'elle est appelée, ou est la taille cache / stockée et que la valeur est simplement accessible? p>
4 Réponses :
Il est probablement inséré au moment de la compilation s'il est connu alors. Sinon, stocké dans une variable. Si ce n'était pas, comment la taille serait-elle calculée? P>
Cependant, vous ne devriez pas faire des hypothèses sur les opérations internes du cadre. Si vous voulez savoir si quelque chose est plus ou moins efficace, testez-le! P>
C'est certainement une mauvaise idée de commencer à cacher / optimiser par vous-même ici. p>
Lorsque vous traitez avec des tableaux, vous devez suivre un chemin standard que l'optimiseur (JIT) peut reconnaître. Si vous le faites, non seulement la propriété de longueur sera mise en cache mais plus importante, la vérification des limites d'index peut être effectuée une fois avant la boucle. p>
Lorsque l'optimiseur perd votre sentier, vous paierez la pénalité d'un contrôle par accès par accès. P>
C'est pourquoi les matrices déchiquetées ( Si vous souhaitez rechercher cela plus loin, la mise en cache que vous proposez est généralement appelée ' Haution 'La propriété de longueur. P> int [] [] [] code>) sont plus rapides que multi-dim ( int [] code>). L'optimisation de int [] code> est simplement manquante. Jusqu'à FX2 de toute façon, je n'ai pas vérifié le statut de ceci à FX4. p>
En outre, la documentation indique "cette méthode est une opération O (1)", suggérant que les frais généraux sont minimes.
Je voulais juste partager un cas que j'ai récemment eu, où cela était en effet un problème. J'étais itération d'un assez grand tableau 2 dimensions plusieurs fois par seconde. Profiler a identifié un goulot d'étranglement sur la propriété de la matrice à l'intérieur pour code> boucle. #1. t [] code> avec .getlength (0) code> et .getlength (1) code> pris en charge ~ 4 mil éléments. # 2. t [] code> avec des propriétés de longueur hémérité autorisée à atteindre ~ 67 mil éléments. # 3. t [] [] code> avec .Length code> Propriétés pris en charge ~ 67 mil éléments mais 30% plus lentement. # 4. t [] [] code> avec une seconde dimension hémulée a montré les mêmes résultats que n ° 2.
La convention de dénomination est une indice. Les méthodes "longueur" (E.G. Array.length) dans .NET renvoient généralement une valeur connue, tandis que les méthodes "Compte" (E.G. List.count) seront / peuvent énumérer le contenu de la collection pour déterminer le nombre d'éléments. (Dans une autre version ultérieure, des méthodes d'extension sont telles que tout ce qui vous permet de vérifier si une collection est non vide sans avoir à utiliser l'opération de comptage potentiellement coûteuse) GetLength ne devrait différer que de longueur dans laquelle vous pouvez demander la dimension que vous souhaitez la longueur. de. p>
Une variable locale est peu susceptible de faire une différence sur un appel à getLength - le compilateur optimisera très bien la plupart des situations de toute façon - ou si vous pourriez utiliser des objets qui n'ont pas besoin de déterminer la longueur avant de commencer. P>
(mais il serait facile d'écrire quelques boucles et de leur temps (avec un compteur de haute performance) pour voir quel effet appels / types différents pourrait avoir sur la vitesse d'exécution. Faire ce type de test rapide peut être un excellent manière d'obtenir des idées dans une langue que vous pourriez ne pas vraiment prendre si vous ne faites que lire les réponses) P>
@HENK: foreach ne peut pas être plus rapide, mais cela ne sera certainement pas plus lent. (Comme vous l'avez dit, faites des choses comme la mise en cache de la longueur pourraient réellement aggraver les choses, tandis que pourach donne à l'optimiseur la meilleure chance de réussir)
Ceci est incroyablement faux. La propriété compteur code> sur icollection tout () code> énumère le (premier élément de) la collection. Nombre () CODE> Appels Nombre CODE> S'il s'agit d'un ICollection code> et énumère autrement la collection.
J'ai dit compter peut i> énumérer la collection. Ceci peut i> (sur certaines collections) est plus lent que la mise en œuvre typique de la longueur, qui n'en énumère conventionnellement rien. La mise en œuvre exacte du nombre dépend de la collecte que vous utilisez. C'est pourquoi i> Microsoft a utilisé la convention de dénomination de comptage / longueur. Peut-être Eric Lippert peut vous convaincre: Blogs .msdn.com / B / ERICLIPPERT / Archive / 2008/05/09 / ...
Nope, il ne peut pas. Ce message de blog décrit énumérable.count () code> comme énumérant la collection, mais jamais le compte code> propriété. Si vous pensez vraiment que compter code> peut énumérer la collection, puis signalez-moi sur un seul type de cadre où il le fait; Je ne crois pas qu'il y en ait. Je serais choqué de voir un exemple. (En outre, j'ai eu l'impression que la Convention était d'utiliser code> code> pour des collections de longueur variable et longueur code> pour des collections de taille fixe (par exemple des chaînes ainsi que des tableaux.))
OK, assez juste, j'ai raté des supports lors de la lecture. Merci pour le pointeur - c'est bon d'apprendre de nouvelles choses.
Si vous avez vraiment besoin que la boucle soit aussi rapide que possible, vous pouvez stocker la longueur dans une variable. Cela vous donnera une légère augmentation de performance, certains tests rapides que j'ai faits montrent qu'il est environ 30% plus rapide. P>
Comme la différence n'est pas plus grande, elle montre que la méthode Ceci va pour des tableaux multidimensionnels, seulement. Pour un tableau de dimension unique, il est en fait plus rapide d'utiliser la propriété code> code> de la boucle, car l'optimiseur peut alors supprimer les vérifications de limites lorsque vous utilisez le tableau dans la boucle. P> getLength code> est vraiment rapide. Sauf si vous avez vraiment besoin de cramner la dernière sortie du code, vous devez simplement utiliser la méthode dans la boucle. P>
Quelqu'un qui lit seulement votre première phrase commencera à faire la mauvaise chose ici. Votre gain de 30% concerne uniquement le cas rare et sous-optimal.