3
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

Rubyで競プロする上で避けたい2つの遅いメソッド

Last updated at Posted at 2019-12-08

注意: この記事はRuby2.3系の頃の話で、現在(2021/05)のAtCoderはruby 2.7系のため、同じ挙動ではないかもしれません。

競プロで避けたい2つのメソッド

ABC 147Dで痛い目を見たのでまとめておきます。
https://atcoder.jp/contests/abc147/tasks/abc147_d

each_with_index

ブロックの外で変数を宣言し、自分でインクリメントしたほうが早い。
596.8 i/s(each_with_index) vs 704.4 i/s(ブロック外変数をインクリメント)
(秒間何回処理を実行できるかの比較)

to_s(2)

Integer#to_s は引数の進数展開してくれますが、これが遅かった。
全bitを確認する場合でも、bit shiftしながら確認していったほうが早いです。
1783.4 i/s(while loop) vs 704.4 i/s(to_s(2))

実行コード
require 'benchmark/ips'

cons = 100.times.with_object([]) { |_i, obj| obj << rand(1 << 60) }
ary_to_s1 = Array.new(60, 0)
ary_to_s2 = Array.new(60, 0)
ary_while = Array.new(60, 0)
ONE = '1'.freeze
Benchmark.ips do |x|
  x.config(:time => 20, :warmup => 0)

  x.report("each_with_index") {
    cons.each do |num|
      num.to_s(2).chars.reverse.each_with_index do |x, i|
        ary_to_s1[i] += 1 if x == ONE
      end
    end
  }
  x.report("index") {
    cons.each do |num|
      index = 0
      num.to_s(2).chars.reverse.each do |x|
        ary_to_s2[index] += 1 if x == ONE
        index += 1
      end
    end
  }
  x.report("while") {
    cons.each do |num|
      tmp = num
      ind = 0
      while tmp > 0
        ary_while[ind] += tmp%2
        tmp = tmp >> 1
        ind += 1
      end
    end
  }

  x.compare!
end
Comparison:
               while:     1783.4 i/s
               index:      704.4 i/s - 2.53x  slower
     each_with_index:      596.8 i/s - 2.99x  slower

Ruby 2.3.3 で確認

3
0
5

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?