Je suis définitivement un débutant à ruby (et en utilisant 1.9.1), donc toute aide est appréciée. Tout ce que j'ai appris sur Ruby a été d'utiliser google. J'essaie de comparer deux tableaux de hachages et en raison des tailles, ça prend beaucoup de temps et flirte avec le manque de mémoire. Toute aide serait appréciée.Ruby: Comparant deux tableaux de hachages
J'ai une classe (ParseCSV) avec plusieurs méthodes (initialiser, ouvrir, comparer, enlever, sortir). La façon dont je l'ai travail est en ce moment comme suit (et cela ne passe les tests que j'ai écrit, tout en utilisant un ensemble de données beaucoup plus faible):
file1 = ParseCSV.new(“some_file”)
file2 = ParseCSV.new(“some_other_file”)
file1.open #this reads the file contents into an Array of Hash’s through the CSV library
file1.strip #This is just removing extra hash’s from each array index. So normally there are fifty hash’s in each array index, this is just done to help reduce memory consumption.
file2.open
file2.compare(“file1.storage”) #@storage is The array of hash’s from the open method
file2.output
Maintenant que je suis aux prises avec est le comparer méthode. Travailler sur des ensembles de données plus petits n'est pas un gros problème et fonctionne assez vite. Cependant, dans ce cas, je compare environ 400 000 enregistrements (tous lus dans le tableau des hachages) contre un qui a environ 450 000 enregistrements. J'essaie d'accélérer ça. Je ne peux pas non plus exécuter la méthode strip sur file2. Voici comment je le fais maintenant:
def compare(x)
#obviously just a verbose message
puts "Comparing and leaving behind non matching entries"
x.each do |row|
#@storage is the array of hashes
@storage.each_index do |y|
if row[@opts[:field]] == @storage[y][@opts[:field]]
@storage.delete_at(y)
end
end
end
end
J'espère que cela a du sens. Je sais que le processus sera lent, car il faudra parcourir 400 000 lignes 440 000 fois chacune. Mais avez-vous d'autres idées pour l'accélérer et éventuellement réduire la consommation de mémoire?
Vous devrez stocker quelque chose en plus hash plaine comme jeu stocke deux hash qui ont le même contenu, mais pas la même identité d'objet que deux objets différents. –
Le traitement de l'égalité de hachage dépend de la version de Ruby. Le code que j'ai fourni est OK dans Ruby 1.8.7 et plus, mais pas pour Ruby 1.8.6. Hash # eql? répond 'vrai' pour deux objets Hash identiques mais différents dans 1.8.7, mais répond 'faux' dans Ruby 1.8.6 – madlep
@Kathy: Etes-vous sûr?Un 'Set' est vraiment juste un' Hash' (si vous regardez l'implémentation, vous verrez que la classe 'Set' délègue simplement' 'Hash'', les' Hash' sont les valeurs 'Set' et' Hash' 'les valeurs sont toutes' true'). Et je suis assez sûr (en fait, je l'ai démontré dans une réponse à une autre question il y a deux jours) que le bug que vous mentionnez a été corrigé dans Ruby 1.9. Je l'ai juste ré-testé et cela semble effectivement fonctionner. –