Ich habe folgendes Szenario:
Ich muss herausfinden, die einzigartige Liste von IDs über eine sehr große Menge.
So zum Beispiel habe ich 6000 Arrays von IDs (Follower-Liste), jeder kann in der Größe zwischen 1 und 25000 (ihre Follower-Liste).
Ich möchte die eindeutige Liste von IDs über alle diese Arrays von IDs (eindeutige Nachfolger von Followern) erhalten. Sobald dies erledigt ist, muss ich eine andere Liste (eine weitere Personennachfolgerliste) von IDs subtrahieren und eine endgültige Zählung erhalten.
Der endgültige Satz eindeutiger IDs wächst auf etwa 60.000.000 Datensätze. In Ruby, wenn die Arrays zu dem großen Array hinzugefügt werden, wird es um einige Millionen sehr langsam. Das Hinzufügen zu dem Set dauert zuerst 0,1 Sekunden, dann wächst es zu mehr als 4 Sekunden bei 2 Millionen (wo ich nicht hin muss).
Ich habe ein Testprogramm in Java geschrieben und es macht die ganze Sache in weniger als einer Minute.
Vielleicht mache ich das in Ruby ineffizient oder es gibt einen anderen Weg. Da mein Hauptcode proprietär ist, habe ich ein einfaches Testprogramm geschrieben, um das Problem zu simulieren:
%Vor%Irgendwelche Vorschläge, ist es Zeit, zu jruby zu wechseln und Sachen wie diese nach Java zu verschieben?
Die Methode, die Sie dort verwenden, ist schrecklich ineffizient, also ist es keine Überraschung, dass dies langsam ist. Wenn Sie versuchen, einzigartige Dinge zu verfolgen, benötigt ein Array viel mehr Verarbeitung als ein Hash-Äquivalent.
Hier ist ein einfaches Refactoring, das die Geschwindigkeit um 100x erhöht:
%Vor% Das Schöne an einem Hash ist, dass Duplikate unmöglich sind. Wenn Sie alle Follower zu einem beliebigen Zeitpunkt auflisten müssen, verwenden Sie all_followers.keys
, um die IDs zu erhalten.
Hashes beanspruchen mehr Speicher als ihre Array-Entsprechungen, aber das ist der Preis, den Sie für die Leistung zahlen müssen. Ich vermute auch, dass einer der großen Speicherverbraucher hier die vielen individuellen Listen von Anhängern sind, die generiert werden und scheinbar nie benutzt werden, also könnten Sie diesen Schritt vielleicht komplett überspringen.
Der Schlüssel hier ist, dass der Array |
-Operator nicht sehr effizient ist, besonders wenn er auf sehr großen Arrays arbeitet.
Hier ist ein Beispiel für die Handhabung von eindeutigen Objekten mit Array, Hash und Set:
%Vor%und ihr Maßstab:
%Vor%Referenzen:
Tags und Links ruby performance jruby