くりにっき

フルスタックキュアエンジニアです

【今月のgem】kiriban_getterというキリ番チェックをするためのgemを作った

社内LT大会ネタで作ったやつ(第2弾)

モチベーション

キリ番には夢がある(断言)

github.com

使い方

refinementsを使っているので

using KiribanGetter

したところでのみ下記のメソッドが使えるようになります

kiriban?

100.kiriban?
#=> true

101.kiriban?
#=> false

111.kiriban?
#=> true

zorome?

111.zorome?
#=> true

2222.zorome?
#=> true

2223.zorome?
#=> false

kuraiban?

100.kuraiban?
#=> true

101.kuraiban?
#=> false

111.kuraiban?
#=> false

余談

  • 「最上位以外の数字が全部0」という数字の名前を調べるのが一番難しかった(いろいろググったら「位番」がしっくり来たので採用)

その他

  • kuraiban? , zorome? ともに何種類か作ってベンチマークとって速いやつを採用
    • Stringや正規表現での判定は整数演算の1.5〜2倍くらい遅いという学び
    • ただしString#lengthはチョッパヤ
  • Rubyでアクセスカウンターを作る時にご利用ください

kiribanとの違い

最初kiribanって名前のgemを作ってpushしようとしたら下記の同名gemがあったので名前を変えてリリースしました(つらい)

secret-garden.hatenablog.com

github.com

  • kiribanはRubyのコアクラス(ObjectやString)をオープンクラスしてメソッドを直接生やしているが、kiriban_getterはrefinementsを使ってるので影響範囲は using KiribanGetter したところのみ
  • kiribanの方が対応してるキリ番は多い
  • kiribanは文字列に変換できるオブジェクトなら AAA のようなやつでもチェックできるが、kirban_getterは Integer のみチェック

ベンチマーク結果

ベンチマークをとったらkiriban_getterの方が速かったです

$ bundle exec ruby benchmark/kiriban_getter.rb
Warming up --------------------------------------
    digit_1 (legacy)    72.272k i/100ms
    digit_2 (v0.1.0)    78.053k i/100ms
Calculating -------------------------------------
    digit_1 (legacy)      1.229M (± 3.0%) i/s -      6.215M in   5.060381s
    digit_2 (v0.1.0)      1.315M (± 4.3%) i/s -      6.635M in   5.057391s

Comparison:
    digit_2 (v0.1.0):  1314506.8 i/s
    digit_1 (legacy):  1229392.4 i/s - same-ish: difference falls within error

Warming up --------------------------------------
kuraiban_1? (legacy)    42.554k i/100ms
kuraiban_2? (v0.1.0)    65.051k i/100ms
zeroban? (kiriban gem)
                         9.175k i/100ms
Calculating -------------------------------------
kuraiban_1? (legacy)    598.862k (± 4.7%) i/s -      3.021M in   5.058023s
kuraiban_2? (v0.1.0)      1.010M (± 2.9%) i/s -      5.074M in   5.027767s
zeroban? (kiriban gem)
                        100.042k (± 5.0%) i/s -    504.625k in   5.057287s

Comparison:
kuraiban_2? (v0.1.0):  1010089.6 i/s
kuraiban_1? (legacy):   598862.0 i/s - 1.69x slower
zeroban? (kiriban gem):   100042.3 i/s - 10.10x slower

Warming up --------------------------------------
  zorome_1? (legacy)    10.264k i/100ms
  zorome_2? (v0.1.0)    25.113k i/100ms
zoroban? (kiriban gem)
                         7.585k i/100ms
Calculating -------------------------------------
  zorome_1? (legacy)    122.994k (± 4.9%) i/s -    615.840k in   5.019815s
  zorome_2? (v0.1.0)    329.715k (± 4.7%) i/s -      1.657M in   5.039460s
zoroban? (kiriban gem)
                         90.235k (± 3.8%) i/s -    455.100k in   5.050971s

Comparison:
  zorome_2? (v0.1.0):   329715.0 i/s
  zorome_1? (legacy):   122994.0 i/s - 2.68x slower
zoroban? (kiriban gem):    90235.3 i/s - 3.65x slower

教訓

  • gemを作る時は https://rubygems.org/ で事前にチェックしよう
  • 空いてたら名前を取られないようにbetaでもいいからリリースすべき