fork download
require 'benchmark'

	puts RUBY_DESCRIPTION

ben = 500000
Benchmark.bm do |x|
  x.report("loop:") {	# 空ループ
    ben.times do
    end
  }
  x.report("700 :") {
    ben.times do
      20201016.to_s(2).split("0").max.size
    end
  }
  x.report("710 :") {
    ben.times do
      n = 20201016
      i = 0
      while n != 0
        n &= n << 1
        i += 1
      end
    end
  }
  x.report("700a:") {
    ben.times do
      20201016.to_s(2)
    end
  }
  x.report("700b:") {
    ben.times do
      "1001101000011111000111000".split("0")
    end
  }
  x.report("700c:") {
    ben.times do
      ["1", "", "11", "1", "", "", "", "11111", "", "", "111"].max
    end
  }
  x.report("700d:") {
    ben.times do
      "11111".size
    end
  }
end

=begin

695 デフォルトの名無しさん 2020/10/16(金) 19:48:26.76 ID:2tllxc0n
    お題
    自然数nを 2進数にした時、 1が連続する個数の最大値を求める。
    例
    20201016 -> 5
-------

Ruby 実装でのベンチマーク 1 : n = 20161016 固定
>>700,710
どちらもコンソール出力処理は省略

700a-d 700を分解してベンチマーク
700a to_s(2)
700b split("0")
700c max
700d size

※考察
700 と 710 の速度比は 5~6倍程度
700 と 700a がほぼ互角だった
文字処理が高速で数値が遅め(リッチだからしょうが無いが)
n を巨大にした場合を別にしらべる


# C言語でアセンブラ出力を見ると
---
	unsigned int n = 20201016;
	unsigned int i = 0;
	while( n ){
		n &= (n << 1);
		++ i;
	}
	printf( "%d\n", i );
---
$ gcc -O2 -S
	xorl	%r8d, %r8d
	movl	$20201016, %eax
.L4:
	leal	(%rax,%rax), %edx
	addl	$1, %r8d
	andl	%edx, %eax
	jne	.L4

=end
Success #stdin #stdout 2.56s 6696KB
stdin
Standard input is empty
stdout
ruby 2.5.5p157 (2019-03-15 revision 67260) [x86_64-linux-gnu]
       user     system      total        real
loop:  0.016000   0.000000   0.016000 (  0.016097)
700 :  1.080000   0.000000   1.080000 (  1.080482)
710 :  0.204000   0.000000   0.204000 (  0.203543)
700a:  0.212000   0.000000   0.212000 (  0.213145)
700b:  0.712000   0.000000   0.712000 (  0.711111)
700c:  0.296000   0.000000   0.296000 (  0.299934)
700d:  0.040000   0.000000   0.040000 (  0.036325)