Chaque itération de chaque “foreach” boucle généré 24 Octets de déchets de la mémoire?
Mon ami travaille avec Unity3D sur C#. Et il m'a dit en particulier:
Chaque itération de chaque “foreach” boucle généré 24 Octets de déchets
mémoire.
Et je vois aussi cette information ici
Mais est-ce vrai?
Le point le plus pertinent à ma question:
Remplacer le “foreach” les boucles avec de simples boucles “for”. Pour une raison quelconque,
chaque itération de chaque “foreach” boucle généré 24 Octets de déchets
de la mémoire. Une simple boucle d'itération 10 fois à gauche 240 Octets de mémoire
prêt à recueillir des données qui a été tout simplement inacceptable
C'est présent trop général un état d'être pris au sérieux. Différentes collections de se comporter de différentes manières avec des
Oui, je pense la même chose. La fin de la 'foreach' plus lent le "pour"?
Il dépend entièrement de la situation spécifique. Toute généralisation sur ce front est susceptible d'être incorrecte dans certaines situation.
Que tout l'article est à lire comme une "Cela a fonctionné pour nous, dans notre situation spécifique". Il peut ou peut ne pas être la même pour vous.
En fait, je dois prendre cet article avec une pincée de sel, parce qu'il revendique "l'Appel de la balise de propriété sur un objet alloue et des copies supplémentaires de la mémoire" - où
foreach
- l'auteur ne précise pas de quoi il parle. (En particulier, avec les tableaux, le compilateur va générer efficacement quelque chose d'équivalent à la for
boucle de toute façon.)Oui, je pense la même chose. La fin de la 'foreach' plus lent le "pour"?
Il dépend entièrement de la situation spécifique. Toute généralisation sur ce front est susceptible d'être incorrecte dans certaines situation.
Que tout l'article est à lire comme une "Cela a fonctionné pour nous, dans notre situation spécifique". Il peut ou peut ne pas être la même pour vous.
En fait, je dois prendre cet article avec une pincée de sel, parce qu'il revendique "l'Appel de la balise de propriété sur un objet alloue et des copies supplémentaires de la mémoire" - où
tag
ici est un string
- désolé, mais que n'est tout simplement pas vrai - tout ce qui se passe, c'est que la référence à la chaîne de l'objet est copié sur la pile, il n'y a aucun objet supplémentaire affectation ici.
OriginalL'auteur jimpanzer | 2013-09-10
Vous devez vous connecter pour publier un commentaire.
foreach
est intéressant bête; beaucoup de personnes pensent, à tort, qu'elle est liée àIEnumerable[<T>]
/IEnumerator[<T>]
, mais qui n'est tout simplement pas le cas. En tant que tel, il est inutile de dire:En particulier, il dépend exactement ce que vous êtes en boucle. Par exemple, un grand nombre de types personnalisés d'itérateurs -
List<T>
, par exemple, a unstruct
à base d'itérateur. La suite alloue zéro objets:Cependant, celui-ci ne les allocations d'objets:
Qui ressemble, mais n'est-ce pas par la modification de la
foreach
pour itérer surIList<SomeType>
(qui n'ont pas une coutumeGetEnumerator()
méthode, mais qui met en œuvreIEnumerable<SomeType>
) nous obligent à utiliser leIEnumerable[<T>]
/IEnumerator<T>
de l'API, dont beaucoup par la nécessité d'impliquer un objet.Modifier avertissement: remarque, je suis en supposant ici que l'unité peut préserver la valeur de type sémantique de la coutume iterator; si l'unité est forcée d'élever des structures d'objets, puis franchement, tous les paris sont éteints.
Comme il arrive, je serais heureux de dire "bien sûr, l'utilisation
for
et un indexeur dans ce cas," si toutes les questions d'attribution, mais fondamentalement: une déclaration générale surforeach
est inutile et trompeuse.Malheureusement, cela semble être incorrecte dans l'Unité (possible avec le Mono en général?) J'ai ajouté un autre commentaire avec un exemple de code qui illustre la poubelle en cours de création. Chaque fois foreach est appelé, 24 octets sont affectées.
Il sert à produire .NET ainsi. Ce n'est pas le
GetEnumerator()
appel, mais leDispose()
. Voir cela.Vous dites "C'est vide de sens à dire...", et il aurait été, à moins que c'est exactement ce qui se passe. À l'aide de C# et Unity3D 4.x (qui utilise Mono), tous itération de tous
foreach
boucle que j'ai observé crée de 24 octets de déchets à collecter.et de nouveau, sans plus de détails de ce que vous êtes en boucle de plus, et ce que les choses se produisent à l'intérieur de la boucle (fermetures, etc), j'affirme: est pas de sens. Si vous parlez d'un scénario, alors vous pouvez commencer à parler de sens. Tout est dans le contexte ici.
OriginalL'auteur Marc Gravell
Votre ami est correct, le code suivant va générer 24k de déchets chaque image dans l'Unité de la version 4.3.4:
Cela montre la répartition dans l'Unité profiler:
Selon le lien suivant c'est un bug dans la version de mono utilisé par l'Unité, que les forces de la structure permet d'obtenir une boîte, ce qui semble être une explication raisonnable si je n'ai pas vérifié à l'aide de code d'inspection: Blog de discuter de la boxe bug
C'est corrigé dans la récente Unité versions (5.5+): q.unity3d.com/questions/1465/...
OriginalL'auteur Chris Blackwell
Il y a quelques bons conseils ici sur foreach, mais je me dois de mentionner à propos de la Marque du commentaire ci-dessus concernant les balises (malheureusement, je n'ai pas assez de rep à commenter ci-dessous son commentaire), où il a déclaré,
En fait, l'appel de la propriété tag permet de créer des ordures. Ma conjecture est que à l'intérieur de l'étiquette sont stockés comme des entiers (ou d'un autre type simple), et lorsque le tag de la propriété est appelée, l'Unité convertit l'int d'une chaîne à l'aide d'un tableau interne.
Il défie la raison, puisque la propriété tag pourrait tout aussi bien retourner la chaîne à partir de cette table interne plutôt que de créer une nouvelle chaîne, mais pour quelque raison que ce soit, c'est la façon dont il fonctionne.
Vous pouvez tester vous-même en utilisant les éléments suivants composant simple:
Si gameObject.la balise n'a pas été la production de déchets, puis d'augmenter/de diminuer le nombre d'itérations n'aurait aucun effet sur la table d'Allocation (dans l'Unité Profiler). En fait, nous voyons une augmentation linéaire de la GC de l'Allocation que le nombre d'itérations augmente.
Il est également intéressant de noter que le nom de la propriété se comporte exactement de la même manière (encore une fois, la raison m'échappe).
OriginalL'auteur Kyle G