2009-11-23 5 views
4

je une routine qui ajoute des éléments ordinaux (type énuméré « jour » ou « nuit ») à un tableau dynamique multidimensionnel, qui est déclarée comme:Grand tableau dynamique - écriture lente

TShiftType = (stDay, stNight); 
TScheduleArray = array of array of array [1..DaysPerWeek] of TShiftType; 

Le tableau pourrait contenir n'importe quoi entre 1 élément (par exemple (Day, Day, Day, Day, Day, Night, Night)) et plus de 20 000 éléments. Chaque élément peut lui-même avoir des sous-éléments selon le nombre de semaines traitées.

donc un élément dans un tableau à deux semaines pourrait ressembler à:

((stDay, stDay, stDay, stDay, stDay, stNight, stNight), (stDay, stDay, stDay, stDay, stDay, stNight, stNight))

Cela va très rapide et fonctionne très bien lorsque le nombre d'éléments est relativement faible (environ en 1000). Une fois que le nombre de semaines et d'éléments augmente, il suffit d'ajouter un nouvel élément au tableau (après avoir appelé SetLength pour augmenter la longueur du tableau) pour ralentir de façon exponentielle.

Parfois je suis aussi une violation d'accès. Lorsque j'utilise la fonction "Rechercher l'erreur" dans Delphi, cela m'amène à la méthode @DynArrayAsg dans la fenêtre CPU. Mais je ne reçois jamais l'exception EOutOfMemory que l'aide de Delphi dit que je recevrais si la mémoire disponible n'était pas suffisante pour réaffecter la variable.

Est-ce ralentissement de l'accès à la mémoire le comportement attendu? J'utilise Delphi 6.

Répondre

7

Oui, car lorsque vous le réaffectez, s'il n'y a pas assez d'espace contigu pour ajouter un seul élément à la fin du tableau existant, il doit trouver un autre bloc suffisamment grand, l'allouer, Copiez l'intégralité de votre tableau existant, puis libérez l'original. Plus votre tableau est grand, plus la copie devient longue. TList aide à atténuer ce problème en allouant sa matrice interne en deux puissances, au lieu de "exactement aussi grand que nécessaire", puis en utilisant une variable Count pour marquer les limites supérieures de ce qui est réellement utilisé . Peut-être que vous pourriez faire quelque chose de similaire?

En outre, si vous ne l'avez pas déjà, se FastMM. Il est beaucoup mieux d'allouer et de réallouer de la mémoire que le gestionnaire de mémoire intégré de Delphi 6.

+0

Merci Mason, bonne explication. J'ai D2009 (pour la partie FastMM) qui attend d'y aller mais un composant tiers est en train de se mettre en travers du chemin pour le moment. Pensez-vous qu'un TList serait une meilleure solution dans ce cas, où j'ai un tableau multidimensionnel? –

+0

Probablement pas, mais vous pouvez regarder la façon dont TList est implémentée et l'utiliser comme un modèle pour construire votre propre classe de tableau en 3 dimensions. –

+0

Merci. Vous avez répondu à la question originale sur les raisons pour lesquelles cela ralentit, merci. –