south37の日記

ちょろっとメモりたい事とかを書く用。もうちょっとちゃんとしたブログもあります。http://south37.hatenablog.com/

ビット演算でオプション

とあるgemのソースを読んでたら、オプションを整数のビット演算で管理していました。 arrayに入れてinclude?で見る場合とどれだけ速度に違いが出るのか、気になったのでベンチとってみた。

                      user     system      total        real
include?: 100000  0.750000   0.000000   0.750000 (  0.755159)
bit: 100000       0.010000   0.000000   0.010000 (  0.011721)

おお、けっこう違う...。こういった高速化が大事なんですかね。

ちなみに、ベンチとったコードは以下。

require 'benchmark'

module Constants
  STRICT      = 0
  RECOVER     = 1 << 0
  NOENT       = 1 << 1
  DTDLOAD     = 1 << 2
  DTDATTR     = 1 << 3
  DTDVALID    = 1 << 4
  NOERROR     = 1 << 5
  NOWARNING   = 1 << 6
  PEDANTIC    = 1 << 7
  NOBLANKS    = 1 << 8
  SAX1        = 1 << 9
  XINCLUDE    = 1 << 10
  NONET       = 1 << 11
  NODICT      = 1 << 12
  NSCLEAN     = 1 << 13
  NOCDATA     = 1 << 14

  options = STRICT | SAX1
  n = 100000
  Benchmark.bm(15) do |x|
    x.report("include?: #{n}") { n.times { Constants.constants.include? :NOENT } }
    x.report("bit: #{n}") { n.times { (options & STRICT) == STRICT } }
  end