2010-09-02 6 views
9

J'ai regardé dans l'implémentation de Array.Resize() et j'ai remarqué qu'un nouveau tableau est créé et retourné. Je vise une allocation de mémoire nulle pendant le jeu et je dois donc éviter de créer de nouveaux types de référence. Le redimensionnement d'un tableau déclenche-t-il le Garbage Collector sur le tableau précédent? Je crée mon propre resizer tableau 2D, mais il fonctionne essentiellement de la même manière que la méthode .NET Resize().Le redimensionnement de tableau invoque-t-il le GC?

Si le nouveau tableau est plus petit que le précédent, mais que les objets en excès ont déjà été replacés dans un pool d'objets génériques, cela appellera-t-il le GC?

Les tableaux seront constamment créés dans ma boucle de jeu, je dois donc essayer de le rendre aussi efficace que possible. J'essaie de créer un array pool en tant que tel, de sorte qu'il ne soit pas nécessaire de continuer à les créer en jeu. Toutefois, si la méthode de redimensionnement fait la même chose, il est peu logique de ne pas simplement instancier un nouveau tableau au lieu d'avoir le pool.

Merci pour l'aide

+0

Peut-être que vous pourriez utiliser 'List ' qui est fondamentalement un tableau redimensionné automatique, et je suppose que lorsque vous le réduire, il ne réduit pas le tableau immédiatement ... mmh je dois vérifier ... – digEmAll

+3

@digEmAll: 'List ' utilise 'T []' en interne mais fait le redimensionnement pour vous. En d'autres termes: il va créer de nouvelles instances. –

+0

Merci pour le suggetsion. Une liste d'une liste m'a traversé l'esprit (car j'utilise des tableaux 2D) mais c'est un peu plus compliqué pour mon jeu. – keyboardP

Répondre

12

Array.Resize ne modifie pas réellement le tableau d'origine du tout - toute personne qui a encore une référence à elle sera en mesure de l'utiliser comme avant. Par conséquent, il n'y a pas d'optimisation possible. Franchement c'est une méthode mal nommé, l'OMI :(

De l'docs:

Cette méthode alloue un nouveau tableau avec la taille spécifiée, copie les éléments de l'ancien tableau à la nouvelle, et remplace l'ancien tableau avec le nouveau.

donc non, il ne va pas réutiliser la mémoire d'origine ou quelque chose comme ça. il est juste de créer une copie peu profonde avec une taille différente.

+0

C'est un bon point. Il aurait mieux valu accepter l'original en valeur et retourner le nouveau. Le passage entier par référence ici pourrait vraiment confondre un programmeur junior dans ce cas. –

+0

Je passais par la méthode dans Reflector et elle ne s'est pas assise juste quand j'ai vu un nouveau tableau en train d'être créé. Je suppose que je vais devoir arriver à un compromis concernant la conception, et effectuer quelques tests de performance. Merci pour la réponse! – keyboardP

2

Oui, en utilisant Array.Resize provoque un nouveau tableau à allouer et l'ancien à recueillir éventuellement (à moins qu'il y a encore des références à quelque part). Un resizer de tableau de plus bas niveau peut éventuellement effectuer une optimisation mineure dans certains cas (par exemple, lorsque le tableau est réduit ou qu'il y a de la mémoire disponible juste après le tableau), mais la mise en œuvre de .NET ne l'est pas. fais ça.

1

Implicitement oui.

Explicitement pas.

1

Toute allocation sera éventuellement nettoyée par le GC lorsqu'il n'y aura plus de références, donc oui.

Si vous voulez éviter de redimensionner vos tableaux, la meilleure chose à faire serait de les préallouer avec une taille suffisamment grande pour éviter de devoir les réaffecter. Dans ce cas, vous pouvez tout aussi bien utiliser une classe de collection avec une capacité initiale spécifiée dans le constructeur, telle que List.

Questions connexes