Celui-ci m'a complètement déconcerté.Python OrderDict sputtering par rapport à dict()
asset_hist = []
for key_host, val_hist_list in am_output.asset_history.items():
for index, hist_item in enumerate(val_hist_list):
#row = collections.OrderedDict([("computer_name", key_host), ("id", index), ("hist_item", hist_item)])
row = {"computer_name": key_host, "id": index, "hist_item": hist_item}
asset_hist.append(row)
Ce code fonctionne parfaitement avec la ligne de collections commentée. Cependant, lorsque je commente la ligne row = dict et supprime le commentaire de la collection, les choses deviennent très étranges. Environ 4 millions de ces lignes sont générées et ajoutées à asset_hist. Donc, quand j'utilise row = dict, toute la boucle se termine en environ 10 millisecondes, ce qui est rapide comme l'éclair. Lorsque j'utilise le dictionnaire ordonné, j'ai attendu plus de 10 minutes et il n'a toujours pas fini. Maintenant, je sais que OrderDict est censé être un peu plus lent qu'une dictée, mais il est supposé être environ 10x plus lent au pire et par mes calculs, il est environ 100 000 fois plus lent dans cette fonction.
J'ai décidé d'imprimer l'index dans la boucle la plus basse pour voir ce qui se passait. Assez intéressant, j'ai remarqué une pulvérisation dans la sortie de la console. L'index s'imprimerait très rapidement sur l'écran, puis s'arrêterait environ 3-5 secondes avant de continuer. Am_output.asset_history est un dictionnaire qui a une clé, un hôte, et chaque ligne est une liste de chaînes. Par exemple.
am_output.asset_history = { "host1": [ "string1", "string2", ...], "host2": [ "string1", "string2", ...], ...}
EDIT: Analyse avec pulvérisation cathodique OrderedDict
mémoire totale sur ce serveur VM: seulement 8 Go ... besoin pour obtenir plus provissioned.
LOOP NUM
184796 (~ 5 secondes d'attente, ~ 60% d'utilisation de la mémoire)
634481 (~ 5 secondes d'attente, ~ 65% d'utilisation de la mémoire)
1197564 (~ 5 secondes d'attente , ~ 70% d'utilisation de la mémoire)
1899247 (~ 5 secondes d'attente, ~ 75% d'utilisation de la mémoire)
2777296 (~ 5 secondes d'attente, ~ 80% d'utilisation de la mémoire)
3873730 (LONG WAIT ... 20 minutes et attendirent abandonnèrent !, 88,3% l'utilisation de la mémoire, le processus est toujours en cours)
Si l'attente se change à chaque course.
EDIT: Redémarrez-la, cette fois-ci, arrêtez-vous sur 3873333, à proximité de l'endroit où elle s'est arrêtée auparavant. Il s'est arrêté après avoir formé la rangée, en essayant d'ajouter ... Je n'ai pas remarqué cette dernière tentative mais elle était là aussi ... le problème est avec la ligne append, pas la ligne row ... Je suis toujours déconcerté. Voici la ligne produite juste avant le long arrêt (ajout de la ligne à l'instruction print) ... hostname modifié pour protéger l'innocent:
3873333: OrderedDict ([('computer_name', 'bg-fd5612ea'), ('id', 1), ('hist_item', "sys1 Normalizer (sys1-4): Le nom de domaine ne peut pas être déterminé à partir de sys1 Nom 'bg-fd5612ea'."))
J'ai du mal à croire que ce que vous observez est dû au comportement 'dict' vs' OrderedDict', est-il possible que quelque chose d'autre change? Je pense aussi que quelqu'un aura du mal à reproduire cela –
Ouais, ils auraient d'abord besoin de générer l'énorme dictionnaire, probablement des générateurs de chaînes aléatoires suffiraient. Mais je suis tout à fait sérieux, quand je déplace le # en bas d'une ligne cela arrive. Il faut aussi noter: quand il est bloqué dans cette boucle en utilisant un dict ordonné et que j'appuie sur Ctrl + C pour arrêter la boucle, c'est comme si rien ne se passait ... Je dois appuyer sur Ctrl + Z pour sortir. – gunslingor
Quelle version de Python? Dans le plus récent, OrderedDict est simplement un alias pour dict, car l'implémentation actuelle est ordonnée par les détails de l'implémentation. – RemcoGerlich