やわらかテック

興味のあること。業務を通して得られた発見。個人的に試してみたことをアウトプットしています🍵

Rubyで巨大な配列を扱う時はEnumeratorを使うのが良さそう

先日、Rubyで巨大な配列(Array)を扱うことがありました。
気になるのは巨大な配列を宣言したときのメモリ使用量です。試しに、要素数が10,000個の配列を宣言してみると89,712Byteほどメモリを使用していることが分かります。

require 'objspace'

# memsize_ofで得られる情報は必ずしも正しいものではありません
list = (1..10000).to_a
puts ObjectSpace.memsize_of(list) # 89712Byte

docs.ruby-lang.org

下のグラフを見て分かるように要素数が増えれば増えるほど、必要なメモリはほぼ線形的に増えていきます。
要素数が一億(100,000,000)もある配列であれば1GB近くのメモリが必要になるようです。

require 'objspace'

def list_mermory_verificator(elm_size)
  list = (1..elm_size).to_a
  puts "Array(size=#{elm_size}): #{ObjectSpace.memsize_of(list)}"
end


list_mermory_verificator(10000) # 89712Byte
list_mermory_verificator(100000) # 1021592Byte
list_mermory_verificator(1000000) # 11636312Byte
list_mermory_verificator(10000000) # 88363080Byte
list_mermory_verificator(100000000) # 1006510416Byte ≒ 0.9373...GB

配列の要素数に上限がない可変長なケースでは、何も考えずに巨大な配列を作ってしまい、メモリを圧迫してしまうことが想像できます。では、どうすれば巨大な配列をメモリの使用量を抑えたまま、扱うことができるでしょうか。

続きを読む

オレオレRspecを自作して覚えるRubyのブロック引数について

Rubyのブロック引数についてご存じでしょうか。
非常に便利な機能で皆さんもよく使っている、正確にはブロック引数に対してブロックを渡していますが、ブロック引数を定義する機会がほとんどない方も多いでしょう。

例: eachの場合

# do以降の処理がブロック引数として受け渡される処理
list = [1, 2, 3, 4, 5]
list.each do |e|
  puts e
end

# 値は1
# 値は2
:
# 値は5

普段、Rubyを書いている方でも何となくでブロック引数を使っている方も多いかもしれませんが、ブロック引数を自在に使うことができるとRubyでの表現の幅がグッと広がります。

続きを読む

【Ruby】boolean型の値を渡すだけの関数にはキーワード引数を付与してあげよう

ある日のこと。Rubyのコードを読んでいるとboolean型の値が引数となる関数の呼び出し処理を見て「なんじゃこりゃ...」という気持ちになりました。簡単な例を紹介します。

def say_hello(is_morning)
  if is_morning
    puts 'おはようございます'
  else
    puts 'こんにちは'
  end
end

say_hello(true) # おはようございます
say_hello(false) # こんにちは

引数のis_morningによって朝であれば「おはようございます」を出力して、朝でなければ「こんにちは」と出力します。

シンプルな関数で挙動は明確ですが、問題なのは呼び出し側です。
呼び出し時にtruefalseを指定することになりますが、関数の詳細を知らなければ呼び出し側で適切な値を選択することができません。同様の理由で、呼び出し側のコードを見た時にtruefalseが何を指すのかが全く分かりません。

say_hello(true) # trueが意味するものとは...?

※Rubyには型がないのでboolean型以外も考慮が必要なんじゃ...と思いますが、今回は省略します。

続きを読む

母の誕生日にヒエログリフのメッセージを送ったら解読してくれた

僕は毎年、母の誕生日に「知識は力なり」という...思いを込めて何かしらの本をプレゼントしています。
過去には「フランス人は10着しか本を持たない」や「52ヘルツのクジラたち」などジャンルを問わず様々な本をセレクトしてきました。「今年は何にしようかな...」と考えていたところ、母が古代エジプトの文明が大好きであることを思い出しました。

母のコレクション

昔はもっと多かったけど「フランス人は10着しか本を持たない」を読んで断捨離したそうです。

自分が古代エジプトについて知っていることはラーの翼神竜の召喚にヒエラティックテキストの詠唱が必要であることぐらいです。しかし、この知識のおかげで古代エジプトの象形文字であるヒエログリフのことを思い出しました。

「ヒエログリフが読み書きできるようになったら面白いかも」と思い、ヒエログリフの知識が得られる本を探したところ...なんと、ありました。

続きを読む

「RubyでつくるRuby」を読んだら簡単なRubyインタプリタが作れた

「RubyでつくるRuby ゼロから学ぶなおすプログラミング言語入門」を読了しました。
非常にチャレンジングな本で、なんとRuby初心者の方に向けてRubyを動かすプログラム、つまりRubyインタプリタを作ってみようという本です。「え、そんなのプログラミング初心者にできるの!?」と気になり、いつのまにかポチっていました(つまり衝動買い)。

今回は「RubyでつくるRuby」の書評をしつつ、どんな方にオススメできるか紹介していきます。

RubyでつくるRuby ゼロから学びなおすプログラミング言語入門www.lambdanote.com

続きを読む