2010-02-19 6 views
8

Si j'ai une immuable carte que je pourrais attendre (sur une période de temps très court - comme quelques secondes) à l'ajout/suppression des centaines de milliers d'articles de, est la norme HashMap une mauvaise idée? Disons que je veux passer 1 Go de données à travers la carte en < 10 secondes de telle sorte que la taille maximale de la carte à un instant est seulement 256 Mo. J'ai l'impression que la carte conserve une sorte d '"historique" mais je vais toujours accéder à la dernière table mise à jour (ie je ne passe pas la carte) parce que c'est une variable membre privée d'un Actor qui est mis à jour/accessible uniquement à partir de réactions internes. Fondamentalement, je soupçonne que cette structure de données peut être (partiellement) en défaut for issues I am seeing around JVMs going out of memory lors de la lecture en grandes quantités de données dans un court laps de temps.mise en œuvre Immuable Carte des énormes cartes

Serais-je mieux avec une implémentation de carte différente et, si oui, de quoi s'agit-il?

Répondre

18

Ouch. Pourquoi devez-vous utiliser une carte immuable? Poubelle médiocre! Les cartes immuables requièrent généralement (log n) de nouveaux objets par opération en plus du temps (log n), ou bien elles enveloppent simplement les mappages de hachage mutables et les changements de couches (ce qui ralentit les choses et peut augmenter le nombre de créations).

L'immunité est excellente, mais cela ne me semble pas être le bon moment pour l'utiliser. Si j'étais vous, je resterais avec scala.collection.mutable.HashMap. Si vous avez besoin d'un accès concurrent, enveloppez Java util.concurrent à la place.

Vous pouvez également augmenter la taille de la nouvelle génération dans la machine virtuelle Java: -Xmn1G ou plus (en supposant que vous utilisez -Xmx3G). En outre, utilisez le garbage collector de débit (parallèle).

+0

Oui - Je l'ai modifié pour utiliser la carte mutable mais je pensais que tout le point de FP était que l'immuabilité était géniale! Cette application devrait facilement fonctionner dans moins de 256 Mo de mémoire à partir d'une perspective «combien de données a-t-elle vraiment besoin à un moment donné». –

+3

La grande immutabilité dépend de l'application. Si vous exécutez une application avec, par exemple, des arborescences de messages envoyés à un groupe de clients, l'immuabilité est une aubaine - vous envoyez simplement l'arborescence actuelle et vous n'avez pas à vous soucier de la structure de données elle-même. de dessous toi. (Vous devez encore attraper des cas comme le client demandant d'ajouter un commentaire à un thread qui est supprimé au moment où ils répondent.) Pour un travail à haut débit dans des structures de données privées qui tournent très rapidement, l'immuabilité offre peu d'avantages et exige beaucoup de frais généraux. –

+0

ouais, c'est ce que je découvre! Alors, comment Haskell ou Clojure se débrouillent-ils dans ces situations? Ne font-ils pas * appliquer * l'immutabilité? –

7

Ce serait horrible. Vous dites que vous voulez toujours accéder à la dernière table mise à jour, cela signifie que vous avez seulement besoin d'une structure de données éphémère, il n'y a pas besoin de payer le coût pour une structure de données persistante - c'est comme gagner du temps et de la mémoire "points de style" discutables. Vous êtes pas construire votre karma en utilisant aveuglément des structures persistantes quand ils ne sont pas appelés.

De plus, une table de hachage est une structure particulièrement difficile à rendre persistante. En d'autres termes, "très, très lent" (fondamentalement, il est utilisable lorsque les lectures sont beaucoup plus nombreuses que les écritures - et vous semblez parler de beaucoup d'écritures). Par ailleurs, un ConcurrentHashMap n'aurait aucun sens dans cette conception, étant donné que la carte est accessible à partir d'un seul acteur (c'est ce que je comprends de la description).

+0

Vous avez raison - je n'ai aucune exigence pour l'immutabilité ou la concurrence. Ma carte est un cache privé à un seul acteur –

+0

Je suppose, puisque vous utilisez des acteurs, que vous voulez profiter des opportunités de simultanéité. Cette carte/acteur, qui ressemble maintenant à un goulot d'étranglement potentiel, pourrait être une bonne opportunité (non pertinente pour les acteurs), vous pourriez bénéficier en faisant de la carte un ConcurrentHashMap partagé (qui n'appartient à aucun acteur) et laisser les auteurs , si possible/raisonnable. –

+0

Les données sont la carte n'a pas besoin d'être partagée entre les acteurs - il y a environ 30 instances d'acteur, chacune avec leurs propres cartes (de données pertinentes uniquement pour eux) –

4

La carte dite (*) immuable de Scala est cassée au-delà de l'utilisation de base jusqu'à Scala 2.7. Ne me faites pas confiance, il suffit de regarder le nombre de billets ouverts pour cela. Et la solution est juste "il sera remplacé par autre chose sur Scala 2.8" (ce qu'il a fait). Donc, si vous voulez une carte immuable pour Scala 2.7.x, je vous conseille de la chercher dans autre chose que Scala. Ou utilisez simplement TreeHashMap à la place.

(*) La carte immuable de Scala n'est pas vraiment immuable. C'est une structure de données mutable en interne, ce qui nécessite beaucoup de synchronisation.

+0

Où puis-je trouver une alternative? Est-ce que 'TreeMap' est OK? Je peux difficilement en trouver un en Java –

+0

@oxbow Je pense que les gens utilisaient 'HashTreeMap' comme une alternative en effet, maintenant que vous le mentionnez. –

+1

La carte immuable de Scala semble avoir été corrigée récemment. Le code est un trie maintenant, l'ancien schéma de journalisation semble avoir disparu. –