Rubyでデータ処理を高速化したいと思っています。
CSVのデータは、次の様に90000行で各20個のデータがあります。
Number,p1,p2,p3,p4,...,p20
00001,48,74,32,74,...,144
00002,98,78,62,71,...,164
00003,49,84,36,41,...,149
.
.
.
89000,78,44,37,81,...,18
90000,88,79,34,15,...,14
※Numberは必ずしも1-90000まであるわけではなく、抜けがあります。またこの例では全て数値ですが意味のある文字が入っていることもあります
これをまずはGDBMへ変換し、その後Marshalで読み込んで使用しています。
読み込みは、Number=00005のとき、p14とp18をひっぱる、Number=00006のときp9とp20をひっぱる、のようにNumberが00001⇒90000まで各行で事前に決めたアルゴリズムに沿って必要なpの値をひっぱってきます。
この、Numberが00001⇒90000までの処理を、ひっぱってくるpの位置を変え数百回繰り返すのですが、処理に時間がかかってしまいこれを高速化したいです。
数百回する部分をThreadで並列処理を試みましたが高速化の効果は得られませんでした。
何かコードに工夫を加えるか、それをも別の方法を使って高速化できないものなのでしょうか。(narrayを使うとか?)。もしくは、rubyで大量のデータ処理は不向きなので、C言語等に取り組むべきなのでしょうか。(rubyは扱いやすく好きなので、できればrubyで達成したいです)
実行しているコードのサンプル
Ruby
1require 'gdbm' 2require "csv" 3 4#DBファイルの作成 5list = GDBM.open("data.db",0664,GDBM::NEWDB) 6 7#CSVからDBファイルへ書き換え 8CSV.foreach("data.csv", headers: true) do |row| 9 key = row["Number"] 10 list[key] ||= Marshal.dump([]) 11 list[key] = Marshal.dump( Marshal.load(list[key]) << row ) 12end 13 14#ここまでの時間は気にならない 15#これより下記の作業をxとyの値を変えて百回繰り返す 16#nowを1から90000まで変えて各行の必要なpをひっぱりだす 17 18100.times{ 19 20now = 1 21answer = [] 22loop{ 23 24 #listにnowの値のキーがあるか確認 25 i = 0 26 until list.has_key?(((now + i).to_i.to_s)) == true 27 i +=1 28 end 29 now = now + i 30 31 #nowが90000に近かったら終わりにさせる 32 if Marshal.load(list[(now + i).to_i.to_s] )[0]["Number"].to_f > 89500 33 exit 34 end 35 36 #Listからpの値をひっぱてくる 37 start = Marshal.load(list[now.to_i.to_s] )[0]["p#{x}"].to_f 38 finish = Marshal.load(list[now.to_i.to_s] )[0]["p#{y}"].to_f 39 answer << [now, start + finish] 40 41 now += 1 42 43} 44 45}
回答1件
あなたの回答
tips
プレビュー
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2019/02/24 16:54
2019/02/24 23:13
2019/02/26 13:04