ruby 上に {long => {long => [long,long,float]}}
というデータ形式で末端が約 30 万件のデータ構造があって
これを以下のようなコードでバイナリにしてファイルに書き出したところ
1 秒もかからずに書き込みできました
puts "#{Time.now.to_i - start_time}\twrite result start" File.open("results.txt", mode = "wb"){|f| results.each{|d,tmp| tmp.each{|a,v| f.write [d,a,v[0],v[1],v[2]].pack('QQQQf') #puts "#{[d,a,v[0],v[1],v[2]]}," } } } puts "#{Time.now.to_i - start_time}\twrite result complete"
これをもう1度 ruby のハッシュに再構築しようと
data = {} start_time = Time.now.to_i puts "reading result start" File.open("results.txt", mode = "rb"){|f| src = f.read puts "#{Time.now.to_i - start_time}\tread result complete: #{src.length}" i = 0 while i < src.length puts i / 36 if i % 36000 == 0 row = src[i...(i+36)].unpack('QQQQf') i += 36 data[row[0]] = {} unless data[row[0]] data[row[0]][row[1]] = row[4] end } puts "#{Time.now.to_i - start_time}\tdata cinstruct complete"
というコードで読もうとしたんですが
なかなかおわらないので1000件ごとにプログレスを表示したところ
1000件ごとに約 3 秒ぐらいかかってしまいます
(ペース的に30万件 1000 秒で約 20 分かかる計算)
書き込みが 1 秒もかからなかったのに
読み込みでなぜこれほど時間がかかるんでしょうか
ディスクからメモリ上(src という変数) には一瞬で読み込めていて
hash を作るループ部分で時間がかかってるようなのです
どうすれば高速に hash データを構築できるでしょうか?
コードのまずいところがあったら指摘していただけると助かります
書き込み形式自体を変更しても構わないです
ファイルサイズや書き込み時間は多少落ちてもいいので
とにかく再構築時間を最速にしたいです
https://qiita.com/Ishotihadus/items/6b48e7606423b714210f
このサイトにいろいろなバイナリの扱いの比較が行われていて
bin_utils がはやいとかかれてるんですが
funny-falcon /
bin_utils
を読む限り連続した同じ型の配列にはできるんですが
pack('QQQQf')
でパックした(36バイトずつの)データを配列に戻す方法がわからず断念しました
ちなみに書き込みはその前の処理の関係で ruby でないとだめなんですが
読み込むほうが同じデータ構造を扱えるなら何でもいいので
ruby でパックしたバイナリが読めるのであれば python とか node.js とかでも大丈夫です
回答2件
あなたの回答
tips
プレビュー
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2020/07/23 01:08