質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.51%
Ruby

Rubyはプログラミング言語のひとつで、オープンソース、オブジェクト指向のプログラミング開発に対応しています。

パフォーマンス

コード効率の向上や計算に関する質問には、このタグを使ってください。

Q&A

2回答

3299閲覧

Rubyで巨大なHashを高速に生成するにはどうすればいいですか?

ttanimichi

総合スコア25

Ruby

Rubyはプログラミング言語のひとつで、オープンソース、オブジェクト指向のプログラミング開発に対応しています。

パフォーマンス

コード効率の向上や計算に関する質問には、このタグを使ってください。

0グッド

1クリップ

投稿2017/07/12 13:57

Ruby で、key, value のペアを300万個くらい持つ Hash を高速に生成したいです。
key は user_id で、value はすべて true です。Ruby のバージョンは CRuby 2.4.1 です。

一応、書いてみたんですけど、

ruby

1ids = User.pluck(:id) # ids の size は約300万 2values = Array.new(ids.size, true) 3 4hash = [ids, values].transpose.to_h

これでどこか遅そうな所ってありますかね?

本当は、

を精読すればいいんだと思うんですけど不勉強で追えてないです。

最後に一発で to_h しているので、たぶんハッシュテーブルの作り直しとかは
発生してないんじゃないかなって気がするんですけど、
ぱっと見でtranspose の部分が遅そうな気もします。

何かもっと効率的な書き方があったら教えてください。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答2

0

1位にはなれなかったです。。。

GC.start r.report "hash" do hash = Hash[ids.map{|x|[x,true]}] end
user system total real transpose 6.800000 0.320000 7.120000 ( 7.143365) zip 7.250000 0.030000 7.280000 ( 7.312942) map 5.670000 0.030000 5.700000 ( 5.707213) simple 5.140000 0.000000 5.140000 ( 5.165525) hash 5.450000 0.020000 5.470000 ( 5.527708)

投稿2017/07/12 17:15

編集2017/07/12 17:25
mattn

総合スコア5030

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

ttanimichi

2017/07/13 04:21

やはり each_with_object の例が一番速いですね...
guest

0

なんかぴったりのメソッドがあれば良いのですが、思いつきません。

Ruby

1require 'benchmark' 2 3ids = 3000000.times.map{rand(0).to_s} 4 5Benchmark.bm 10 do |r| 6 GC.start 7 r.report "transpose" do 8 values = Array.new(ids.size,true) 9 hash = [ids,values].transpose.to_h 10 end 11 values = nil 12 hash = nil 13 GC.start 14 r.report "zip" do 15 values = Array.new(ids.size,true) 16 hash = ids.zip(values).to_h 17 end 18 values = nil 19 hash = nil 20 GC.start 21 r.report "map" do 22 hash = ids.map{|x| [x,true]}.to_h 23 end 24 hash = nil 25 GC.start 26 r.report "simple" do 27 hash = ids.each_with_object({}){|x,h| h[x]=true} 28 end 29end

ごく普通に書いた物が一番速いようです。

user system total real transpose 4.120000 0.260000 4.380000 ( 4.375555) zip 3.060000 0.140000 3.200000 ( 3.205306) map 3.650000 0.080000 3.730000 ( 3.736584) simple 1.940000 0.050000 1.990000 ( 1.994798)

投稿2017/07/12 15:10

otn

総合スコア84380

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

ttanimichi

2017/07/12 15:20

最後の each_with_object の例がこのなかでは一番速いの意外な感じがしますね。ぱっと見、何度もハッシュテーブルを作り直しそうに見えるんですが
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.51%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問