Tech Racho エンジニアの「?」を「!」に。
  • Ruby / Rails関連

週刊Railsウォッチ: Ruby 3.2のベンチマーク記事、dry-cliで高度なCLIを作るほか(20230201後編)

こんにちは、hachi8833です。

週刊Railsウォッチについて

  • 各記事冒頭には🔗でパーマリンクを置いてあります: 社内やTwitterでの議論などにどうぞ
  • 「つっつきボイス」はRailsウォッチ公開前ドラフトを(鍋のように)社内有志でつっついたときの会話の再構成です👄
  • お気づきの点がありましたら@hachi8833までメンションをいただければ確認・対応いたします🙏

TechRachoではRubyやRailsなどの最新情報記事を平日に公開しています。TechRacho記事をいち早くお読みになりたい方はTwitterにて@techrachoのフォローをお願いします。また、タグやカテゴリごとにRSSフィードを購読することもできます(例:週刊Railsウォッチタグ)

お知らせ

今回の週刊Railsウォッチ後編は20230125前編に続くものですが、編集・社内レビューの都合上、先に昨日の20230131前編を公開しました。結果として「前編、前編、後編」という順序での公開となっています。紛らわしくなったことをお詫びします🙇

🔗Ruby

🔗 Ruby 3.2.0リリース関連の記事


つっつきボイス:「Ruby 3.2.0が予定通り昨年末にリリースされたので、関連記事がいくつか出ていました: 上は@ko1さんによるRubyインタプリタの裏話記事です」「テスト実行効率向上のために自宅に実マシンを置いてやってるんですね」

「上の記事はだいたい知っている内容だったんですが、1つ知らない機能が入ってました↓」「Struct.newkeyword_init: trueを指定しなくてもPoint.new(x: 2, y: 3)のようにキーワード引数としてアクセスできるようになった: これはRuby本体というよりはStructクラスの改良ですね」

# https://nithinbekal.com/posts/ruby-3-2/より
# Ruby 3.1
Point = Struct.new(:x, :y, keyword_init: true)

# Ruby 3.2
Point = Struct.new(:x, :y)

Point.new(x: 2, y: 3)
#=> #<struct Point x=2, y=3>

参考: class Struct (Ruby 3.2 リファレンスマニュアル)

🔗 Ruby 3.2のベンチマーク記事

「Ruby 3.2.のベンチマーク記事も出ていました↑」「1本目はhexapdfのPDF生成、kramdowngeom2dを使って測定しているんですね」「YJITのオンオフによる結果は測定対象による感じだけど、全般にRubyバージョンが新しいほど速くなっているっぽい」

「2つ目の記事は、YJITありとなしをdry-rbシリーズのdry-validationとdry-structを中心に試してるんですね: dry-rbシリーズのようにほぼRubyで書かれたライブラリではYJITがよく効きそう👍」「Ruby 3.2+YJITありだと、virtusなどの他の類似ライブラリよりdry-structがかなり速くなってる↓」「記事末尾で著者がdry-rbコア開発者のNikitaさんに"どうやってこんなに速くしたの?"と尋ねたら"最適化しただけだよ"と回答したそうです」

# 同記事より: Ruby 3.2 with YJIT 😱 ⚡
Warming up --------------------------------------
              virtus     8.977k i/100ms
     fast_attributes    96.806k i/100ms
              attrio    20.130k i/100ms
          dry-struct   111.189k i/100ms
Calculating -------------------------------------
              virtus     88.392k (± 1.7%) i/s -    448.850k in   5.079484s
     fast_attributes    973.297k (± 1.3%) i/s -      4.937M in   5.073376s
              attrio    197.840k (± 3.7%) i/s -      1.006M in   5.095283s
          dry-struct      1.103M (± 1.6%) i/s -      5.559M in   5.042373s

Comparison:
          dry-struct:  1102846.4 i/s
     fast_attributes:   973296.6 i/s - 1.13x  (± 0.00) slower
              attrio:   197840.1 i/s - 5.57x  (± 0.00) slower
              virtus:    88391.5 i/s - 12.48x  (± 0.00) slower

参考: dry-rb - Home

dry-rb/dry-validation - GitHub
dry-rb/dry-struct - GitHub

@solnic @joeldrapper デフォルトではYJITは30回呼び出されたメソッドを最適化する(この値はコマンドラインのパラメータで変更可能)。しかしメソッドの利用頻度が高くない場合はYJITはあまり有効でないので、単体テストでのYJITの利用は原則としておすすめしない。
Noah Gibbs

Benchmarking Ruby 3.2 with YJIT - by Peter Solnicaの引用より(強調は編集部)

🔗 Rubyでバイナリヒープを説明する(Ruby Weeklyより)


同記事より


つっつきボイス:「かなり長い記事です」「このbinaryは二分木とかを指すヤツですね」「大学の授業で扱いそうな内容: 興味のある人はどうぞ」

参考: 二分ヒープ - Wikipedia

🔗 dry-cliで高度なCLIツールを作る

dry-rb/dry-cli - GitHub


つっつきボイス:「Hanamiの技術ブログです」「dry-cliって前はdry-rbシリーズの中になかったっぽいので最近追加されたのかも」「どこかで見たような気もしますね」「CLIを作りやすくするツールでしょうか?」「そうそう、似たようなライブラリを使った覚えはあります」

# 同記事より
module HanamiMastery
  module CLI
    class Unshot < Dry::CLI::Command
      desc 'Removes shot marks from a given article (i.e. """)'

      argument :episode, type: :integer, required: true, desc: "Episodes ID to unshot"

      def initialize
        @repository = HanamiMastery::Repositories::Episodes.new
        @transformation = Transformations::Unshot.new
      end

      attr_reader :transformation, :repository

      def call(episode:, **)
        content = repository.read(episode)
        processed = transformation.call(content, one: false)
        repository.replace(episode, processed)
      end
    end
  end
end

「コマンドオプションのパーサーを自分で書こうとするとなかなか面倒ですが、こういうふうにDSLで書けるということですね↑」「dry-cliのリポジトリを見るとHanamiがスポンサーになってる」「この種のツールは本当にいろいろあるんですが、メンテが止まったりすることもよくあるので、dry-rbシリーズになっているなら安心度が高そう👍」

🔗 Ruby 3.2に導入されたEnumerator::productRuby Weeklyより)


つっつきボイス:「Enumerator::productというのが追加されたそうです」「kazzさんの好きそうなメソッド」「cartesian productはデカルト積」「Array#productは前からあったけど、Enumeratorに入ったことで配列以外でも使えるようになったのか👍」「行列の積を求めるときに使うヤツ」「行列忘れちゃったけど、たまに必要になるんですよね」

# 同記事より
array_1 = [1, 2, 3]
array_2 = [:a, :b, :c]

# Cartesian product
[[1, :a], [1, :b], [1, :c], [2, :a], [2, :b], [2, :c], [3, :a], [3, :b], [3, :c]]

参考: product -- class Enumerator - RDoc Documentation -- ドキュメントはまだ英語版のみ
参考: Array#product (Ruby 3.2 リファレンスマニュアル)
参考: 直積集合 - Wikipedia -- デカルト積

🔗 その他Ruby


つっつきボイス:「1つ目はrubygems.orgの認証でハードウェアトークンとPasskeyもサポートされるようになったというお知らせです」「プラットフォームへの攻撃が増えているので、こういうサポートは大事👍」

参考: パスキーとは【用語集詳細】

「2つ目は2/28(土)に開催される福岡Rubyist会議です」「基調講演のぺんさん(@tompng)の"TRICK 2022 Gold Medalist"という肩書が最強すぎる」「この方はTRICKの常連さんですね」「これだけで説明できるのすごい」「そういう人になりたい」

🔗DB

🔗 PostgreSQL 16に追加されたrandom_normal()Postgres Weeklyより)


つっつきボイス:「PostgreSQL 16はまだリリースされていませんが↓、random_normal()という関数が追加されたという記事を見つけました」

参考: PostgreSQL 16 - pgPedia - a PostgreSQL Encyclopedia -- 2023年後半にリリースの見通しとのこと

「normalはnormal distribution(正規分布)のことなんですね」「いわゆるベルカーブ」「通常の乱数ではなく、正規分布する"偏りを持った"乱数を生成するのか: SQL関数として実装されたのは面白い」

-- 同記事より
=$ SELECT
    round(
        random_normal(10, 0.3)::pg_catalog.numeric,
        1
    ) AS v,
    count(*),
    repeat('#', (count(*) / 100)::int4)
FROM
    generate_series( 1, 100000 )
GROUP BY
    1
ORDER BY
    1;
  v   | count |                                                                repeat                                                                 
------+-------+---------------------------------------------------------------------------------------------------------------------------------------
  8.6 |     1 | 
  8.7 |     3 | 
  8.8 |     5 | 
  8.9 |    16 | 
  9.0 |    44 | 
  9.1 |   152 | #
  9.2 |   353 | ###
  9.3 |   895 | ########
  9.4 |  1818 | ##################
  9.5 |  3305 | #################################
  9.6 |  5397 | #####################################################
  9.7 |  8177 | #################################################################################
  9.8 | 10542 | #########################################################################################################
  9.9 | 12642 | ##############################################################################################################################
 10.0 | 13300 | #####################################################################################################################################
 10.1 | 12559 | #############################################################################################################################
 10.2 | 10542 | #########################################################################################################
 10.3 |  8051 | ################################################################################
 10.4 |  5464 | ######################################################
 10.5 |  3388 | #################################
 10.6 |  1861 | ##################
 10.7 |   824 | ########
 10.8 |   392 | ###
 10.9 |   191 | #
 11.0 |    49 | 
 11.1 |    19 | 
 11.2 |     7 | 
 11.3 |     3 | 
(28 rows)

参考: 正規分布 - Wikipedia

🔗クラウド/コンテナ/インフラ/Serverless

🔗 Google Cloudで静的Webページを配信


つっつきボイス:「ざっと見たところ、静的Webページを配信するだけなのにいろいろ作業が必要そうな感じかな」「GitHub Pagesの方が楽そうですね」「でもGitHub Pagesは商用利用が原則禁止ですし、リポジトリ容量や転送量にも上限があるんですよ」「あ、そうでしたか」

参考: クラウド コンピューティング サービス  |  Google Cloud
参考: GitHub Pages について - GitHub Docs

禁止される用途
GitHub Pages は、オンライン ビジネス、eコマース サイト、主に商取引の円滑化またはサービスとしての商用ソフトウェア (SaaS) の提供のどちらかを目的とする、その他の Web サイトを運営するための無料の Web ホスティング サービスとしての使用を意図したものではなく、またそのような使用を許可するものでもありません。 GitHub Pages サイトは、パスワードやクレジットカード番号といった機密情報のやりとりに使うべきではありません。
さらに、GitHub Pages の使用には、一獲千金を狙った計画、わいせつなコンテンツ、暴力的あるいは脅迫的なコンテンツや活動に関する制限など、GitHub 利用規約が適用されます。
GitHub Pages について - GitHub Docsより

「今ならS3 Static Website HostingとかCloudflare Pagesとかにデプロイする方が圧倒的に楽なんじゃないかな」「たしかに」「値段はCloudflare Pagesが有利ですね」

参考: ウェブサイト - ユースケース別クラウドソリューション | AWS
参考: Pages | フロントエンド開発者のためのフルスタックプラットフォーム | Cloudflare

🔗言語/ツール/OS/CPU

🔗 MAGIシステムをGPT3で作った話


つっつきボイス:「MAGIシステムをGPT3で作る話は面白かった」「エヴァンゲリオンに出てきたヤツでしたっけ」「中二ごころをくすぐられるヤツ」「MAGIシステムってたしか元ネタがあった気がする」「自分がそれっぽいものを最初に見たのは小松左京の『果しなき流れの果に』というSF小説↓で、衛星軌道上の3台のコンピュータによる多数決でした」「MAGIは多数決ではなくて合議制なので、カスパーだけ抵抗し続けたりしてましたね」「でないとそこで話が終わっちゃう」

参考: 果しなき流れの果に - Wikipedia

🔗 DeepL Write

「DeepLがベータリリースしたDeepL Writeは英語とドイツ語の自然な文章を提案するというサービスで、気になってます」「ちゃんとアメリカ英語とイギリス英語を区別するのか、よさそう」「論文書く人たちが大喜びしそうですね: 自分が学生だったときに欲しかったヤツ」「同意です」「日本人が自然な英文を書くのは大変すぎ」「人力で英文をブラッシュアップするサービスも以前からありますし」「DeepL Writeが普及したらそういう仕事が消えていくのかも」

🔗 スターリンク値下げと航空機への拡大


つっつきボイス:「航空機対応はスターリンク自身も以前から打ち出してましたね」「スターリンクのビジネスとしては今がちょうど勝負の分かれ目なのかなと思ったりしました: ずっと前にモデムをばらまいていたヤフーBBみたいな状態」「わかりやすい😆」「スターリンクがここで事業を伸ばせるかどうかでしょうね」

「そういえばスターリンクは電波天文台の上空では干渉を避けるために出力を下げているみたいな記事を少し前に見かけました」「スターリンクがそれをやらなかったら大変」

参考: NSFとSpaceX社が電波スペクトラムに関する調整協定を締結 « デイリーウォッチャー|研究開発戦略センター(CRDS)

「スターリンクは日本のような地理状況の国で恩恵が大きそう」「まだ知り合いで買った人はいないかな」「キャンプとかで使えたら楽しそう」「スターリンクは天頂の見えないベランダみたいな環境だと衛星をキャッチできなくなるらしいんですよ」「屋上みたいに全天が見えるところに設置しないとだめなのかな」

参考: 衛星インターネット「Starlink」が届いたので中身を確認。だけど設置はどうする?(CloseBox) | テクノエッジ TechnoEdge


後編は以上です。

バックナンバー(2023年度第1四半期)

週刊Railsウォッチ: Evil Martiansが使っているgem、JavaScriptガイドが更新ほか(20230131前編)

ソースの表記されていない項目は独自ルート(TwitterやはてブやRSSやruby-jp SlackやRedditなど)です。

Ruby Weekly

RubyFlow

160928_1638_XvIP4h

Postgres Weekly

postgres_weekly_banner


CONTACT

TechRachoでは、パートナーシップをご検討いただける方からの
ご連絡をお待ちしております。ぜひお気軽にご意見・ご相談ください。