[RUBY] Geschwindigkeitsvergleich, wenn die Werteseite von Hash alles mit Array abrufen möchte

TL;DR Die Werteseite ist

--Wenn Sie alles in einer Tiefe von 2 oder mehr abflachen möchten values.flatten ist schnell, aber ich mag es, weil es sich nicht so sehr von each_value + flatten unterscheidet.

Ausführungsumgebung Ruby 2.7.1

Muster

sample = { a: [1, 2, 3], b: [2, 3, 4], c: [3, 4, 5] }
  1. each
ary = []
sample.each { |_k, v| ary.concat(v) }
ary
# =>  [1, 2, 3, 2, 3, 4, 3, 4, 5]
  1. each_value
ary = []
sample.each_value { |v| ary.push(*v) } #Das obige Beispiel ist auch mit Push anstelle von Concat in Ordnung
ary
# =>  [1, 2, 3, 2, 3, 4, 3, 4, 5]
  1. values + flatten
sample.values.flatten
# =>  [1, 2, 3, 2, 3, 4, 3, 4, 5]
  1. flat_map
# ruby 2.Wenn es 7 ist,
sample.flat_map { _2 }
# =>  [1, 2, 3, 2, 3, 4, 3, 4, 5]

# _Wenn 2 nicht verwendet werden kann
sample.flat_map { |_, v| v }
# =>  [1, 2, 3, 2, 3, 4, 3, 4, 5]

# flat_Wenn Sie hier zeigen möchten, welchen Wert der Empfänger der Karte hat, ist es möglicherweise eine gute Idee, diese zu schreiben.
sample.flat_map { |_, number_ary| number_ary }
# =>  [1, 2, 3, 2, 3, 4, 3, 4, 5]

Prüfung

Test 1

Wenn Sie den Wert von Tiefe 1 als flaches Array abrufen möchten

Die Ergebnisse sind wie folgt. (Da es die Häufigkeit ist, mit der die Schleife pro Sekunde gedreht werden kann, ist die große schneller.)

Comparison:
          each_value:  2859228.9 i/s
         each concat:  2745728.9 i/s - same-ish: difference falls within error
       flat_map(_,v):  1986117.7 i/s - 1.44x  (± 0.00) slower
        flat_map(_2):  1971975.8 i/s - 1.45x  (± 0.00) slower
      values flatten:   918971.6 i/s - 3.11x  (± 0.00) slower

Testcode
require 'benchmark/ips'

sample = { a: [1, 2, 3], b: [2, 3, 4], c: [3, 4, 5] }

def method_1(h)
  ary = []
  h.each { |_k, v| ary.concat(v) }
  ary
end

def method_2(h)
  ary = []
  h.each_value { |v| ary.push(*v) }
  ary
end

def method_3(h)
  h.values.flatten
end

def method_4(h)
  h.flat_map { _2 }
end

def method_5(h)
  h.flat_map { |_, v| v }
end


Benchmark.ips do |x|
  x.config(:time => 20, :warmup => 2)

  x.report("each concat") { method_1(sample) }
  x.report("each_value ") { method_2(sample) }
  x.report("values flatten") { method_3(sample) }
  x.report("flat_map(_2)") { method_4(sample) }
  x.report("flat_map(_,v)") { method_5(sample) }

  x.compare!
end

Test 2

Wenn Sie alles in einer Tiefe von 2 abflachen und herausnehmen möchten

Comparison:
       values flatten:   800647.1 i/s
   each_value.flatten:   759526.1 i/s - 1.05x  (± 0.00) slower
     flat_map flatten:   676500.5 i/s - 1.18x  (± 0.00) slower
each_value in flatten:   468859.1 i/s - 1.71x  (± 0.00) slower
Testcode
require 'benchmark/ips'

sample = { a: [1, 2, [3]], b: [2, 3, [4]], c: [3, 4, [5]] }

def method_1(h)
  ary = []
  h.each_value { |v| ary.push(*v.flatten) }
  ary
end

def method_2(h)
  ary = []
  h.each_value { |v| ary.push(*v) }
  ary.flatten
end

def method_3(h)
  h.values.flatten
end

def method_4(h)
  h.flat_map { _2 }.flatten
end


Benchmark.ips do |x|
  x.config(:time => 20, :warmup => 2)

  x.report("each_value in flatten") { method_1(sample) }
  x.report("each_value.flatten") { method_2(sample) }
  x.report("values flatten") { method_3(sample) }
  x.report("flat_map flatten") { method_4(sample) }

  x.compare!
end

Fazit

In der Tiefe 1

Es ist am schnellsten mit jedem_Wert zu tun. (Es unterscheidet sich nicht wesentlich von der Verwendung der einzelnen Werte, aber normalerweise ist jeder Wert unter Berücksichtigung der Lesbarkeit) Wenn es sich um flat_map handelt, ist der Rückgabewert der gewünschte Wert und es ist einfach, die Methodenkette fortzusetzen, aber es ist spät values.flatten ist ziemlich langsam

Wenn Sie alles in einer Tiefe von 2 oder mehr flach machen möchten

values.flatten ist schneller, aber ähnlich wie each_value + flatten.

Ausführungsumgebung Ruby 2.7.1

Recommended Posts

Geschwindigkeitsvergleich, wenn die Werteseite von Hash alles mit Array abrufen möchte
So rufen Sie den Hashwert in einem Array in Ruby ab
[Ruby] So rufen Sie den Inhalt des Doppel-Hash ab
Versuchen Sie, die Idee eines zweidimensionalen Arrays mit einem eindimensionalen Array nachzuahmen
So zeigen Sie 0 auf der linken Seite des Standardeingabewerts an
So geben Sie den Wert aus, wenn sich ein Array im Array befindet
Die Geschichte von toString () beginnt mit der Übergabe eines Arrays an System.out.println
[Ruby] Ich möchte nur den Wert des Hash und nur den Schlüssel extrahieren
So konvertieren Sie ein Array von Strings mit der Stream-API in ein Array von Objekten
Ich habe versucht, die Geschwindigkeit von Graal VM mit JMH zu messen und zu vergleichen
Immerhin wollte ich den Inhalt von MySQL mit Docker in der Vorschau anzeigen ...
[Hinweis] [Anfänger] Schreiben, wenn der Wert eines Array-Elements in einem sich wiederholenden Satz von Ruby geändert wird
Was ich versucht habe, als ich alle Felder einer Bohne bekommen wollte
Initialisieren Sie das Ruby-Array mit 0 für Java, dh setzen Sie den Standardwert auf 0
Achten Sie bei Verwendung des Float-Typs auf die Grenzprüfung des Eingabewerts
Geben Sie den Standardwert mit @Builder of Lombok an
So ermitteln Sie den Gesamtwert, den Durchschnittswert usw. eines zweidimensionalen Arrays (mehrdimensionales Array) -java
Anfordern durch Übergeben eines Arrays an eine Abfrage mit dem HTTP-Client von Ruby
Zusammenfassung der Verwendung des im IE festgelegten Proxy-Sets bei der Verbindung mit Java
Listen Sie den Inhalt von Kategorien auf, die mit Active Hash erstellt wurden
Wenn der Schwebeflug von Eclipse schwer zu sehen ist
Geschwindigkeitsvergleich zum Zeitpunkt der Generierung zum Zeitpunkt der Datumskonvertierung
Konvertieren Sie das Array von error.full_messages in Zeichen und geben Sie es aus
[Java] So erhalten Sie den Maximalwert von HashMap
Beim Zuweisen zu einem Array wird ein Nullwert eingegeben
So geben Sie ein Array für den Rückgabewert / das Rückgabeargument einer Methode in der CORBA IDL-Datei an
Gibt an, ob die Serverseite zum Zeitpunkt der Systemwiederherstellung mit Kotlin oder Java erstellt werden soll