Ich wollte nur mehrere Arrays in Ruby verketten und konnte keinen zufriedenstellenden Weg finden.
Beispieleingabe:
%Vor%Erwartetes Ergebnis: (ohne die vorhandenen Arrays zu ändern)
%Vor%Meine tatsächlichen Arrays sind viel größer, also bin ich an einer effizienten Lösung interessiert. Es kann auch mehr als drei Arrays geben, daher wird eine kurze Syntax bevorzugt.
foo + bar + baz
ist das Offensichtliche, es ist prägnant und klar. Aber es wird als (foo + bar) + baz
ausgewertet. Mit anderen Worten: Es wird ein intermediäres Array [1, 2, 3, 4, 5, 6]
erstellt, das nach der gesamten Operation verworfen wird. Wie in der Dokumentation erwähnt:
die wiederholte Verwendung von
+=
auf Arrays kann ziemlich ineffizient sein
[*foo, *bar, *baz]
enthält im Grunde die Elemente, was auch für große Arrays nicht sehr effizient ist. Es sieht auch eher wie ein Hack für mich aus.
[foo, bar, baz].flatten(1)
scheint sogar noch schlechter zu sein als das oben genannte, was die Leistung angeht.
[].concat(foo).concat(bar).concat(baz)
ist am schnellsten, aber es sieht umständlich aus und erfordert mehrere Methodenaufrufe.
Sollte es für solch eine grundlegende Aufgabe keine einfache Klassenmethode geben? Etwas wie:
%Vor%Vermisse ich etwas Offensichtliches?
Ich habe einen anderen Benchmark erstellt, der +
, concat
und eine benutzerdefinierte C-Erweiterung mit einer variablen Anzahl von Arrays vergleicht.
concat
plus
wird sehr langsam, wenn Sie viele Arrays Obwohl "2-3x" nach einer großen Verbesserung klingt, sind es in absoluten Zahlen nur wenige Millisekunden. Ich habe einen größeren Unterschied erwartet, da ich das Array nicht neu skalieren muss, aber das ist offensichtlich kein großer Faktor.
IMO, concat
ist ein anständiger Darsteller und ich sehe keinen dringenden Bedarf für eine C-Erweiterung.
Meine Test-Arrays enthalten nil
-Werte. Andere Elemente scheinen (relativ gesehen) keine unterschiedlichen Ergebnisse zu liefern.
Ich habe flat_map
nicht eingeschlossen, weil dies gleichbedeutend mit concat
ist.
plus
wird von den folgenden Ergebnissen ausgeschlossen
Testcode:
%Vor% C extension: (eigentlich ein Patch, ich habe das zu Rubys array.c
hinzugefügt)
Sie müssen diese Methode in Init_Array
über:
Hat einige Benchmarks und einfache + ist am effizientesten. Daher würde ich vorschlagen, die Zwischenerstellung eines Arrays zu vernachlässigen.
Sie könnten so eine neue Methode concat_all zu Array hinzufügen, aber Sie müssten auch gemischte und mehrdimensionale Arrays berücksichtigen.
%Vor%Hier meine Benchmarks
%Vor%Und hier die Ergebnisse
%Vor%Tags und Links ruby arrays concatenation