k0kubun's blog 2024-01-19T14:51:45+09:00 k0kubun Hatena::Blog hatenablog://blog/12921228815719283850 AIにプログラミング作業を奪われている hatenablog://entry/6801883189076272690 2024-01-19T14:51:45+09:00 2024-01-19T14:59:55+09:00 せっかく10年以上かけて学んだプログラミングだが、人間がコード書くよりChatGPTにやらせた方が早いなということが度々あり、だんだん自分でプログラミングをやる時間が減ってきた。AIにコードを書かせてそれをGitHubにコピペして残りの時間は遊んでるだけで成果が出てお給料ももらえる日は近いし、段々会社もそのことがわかってきて失職する日も近い。 残念ながら現時点では全ての仕事がAIで上手くいくわけではないが、どういう時に使えるかを知っておくと楽をしやすくなるので、僕がどう使っているかをまとめておく。 失職できるケース 簡単なスクリプトを高速に書かせる 僕はRubyが全ての言語の中で一番慣れており… <p>せっかく10年以上かけて学んだプログラミングだが、人間がコード書くよりChatGPTにやらせた方が早いなということが度々あり、だんだん自分でプログラミングをやる時間が減ってきた。AIにコードを書かせてそれをGitHubにコピペして残りの時間は遊んでるだけで成果が出てお給料ももらえる日は近いし、段々会社もそのことがわかってきて失職する日も近い。</p> <p>残念ながら現時点では全ての仕事がAIで上手くいくわけではないが、どういう時に使えるかを知っておくと楽をしやすくなるので、僕がどう使っているかをまとめておく。</p> <h1 id="失職できるケース">失職できるケース</h1> <h2 id="簡単なスクリプトを高速に書かせる">簡単なスクリプトを高速に書かせる</h2> <p>僕はRubyが全ての言語の中で一番慣れており、StackOverflowやドキュメントをほぼ見ずに大抵のプログラムを書き切れるため、Rubyを書いている時がプログラマとして一番生産性が高いのだが、それでも最近AIにRubyを書かせたことがあった。</p> <p>数行で書けるほど単純ではないが複数ファイルが必要なほど複雑でもないみたいな時、欲しい仕様を入力する時間が十分に短ければAIにやらせた方が生産性が高いことになる。人間が次に何を書くかを考えながらキーボードタイプするより、言語モデルがテキストを出力する方が圧倒的に高速なので、当然そういうことになる。</p> <p>具体的に何に使ったかというと、本番環境で走っているアプリケーションサーバーのワーカーのメモリ使用量に各コンテナ内で偏りがあり、アプリ内から取っているメトリクスはリクエストが来た時にしか飛ばないので、メモリ使用量の分布をプロセスの外から調べて綺麗に整形するスクリプトが欲しいということがあり、それを書かせた。</p> <p>成果物は<a href="https://gist.github.com/k0kubun/6abfa1f3f7bdd56ac03e800706bd92ce">これ</a>なのだが、要件を伝えて、何度か出力の整形方法に関してフィードバックするだけで完成した。まあこんなのは書いてても楽しくも何ともないので、AIにやらせたらいいと思う。</p> <h2 id="書くのが面倒な言語を書かせる">書くのが面倒な言語を書かせる</h2> <p>どこでもRubyが使えたら僕は楽なのだが、世の中には主なスクリプト言語としてPythonを採用しているツールがそこそこある。仕事で長い間使っていたこともあるし僕も普通に書ける言語ではあるのだが、たまにStackOverflowを見に行かないといけない程度には不慣れなのでそういう点で面倒くさい。</p> <p>そういったツールの一つがLinux perfというプロファイリングツールで、これはプロファイル結果をスクリプトに集計させるperf scriptという機能があるのだが、Pythonなどの言語で書かないといけない。perf scriptは何度も書いたことがあるが、Pythonは僕はStackOverflowを開かないと書けないのが面倒くさいのでAIにやらせることにした。</p> <p>とりあえず書かせてみたら、perf scriptのインターフェースを何故か知らなかったようなので、以前書いたスクリプトをコピペしたところ仕様を理解してもらえた。その後は欲しい仕様を伝えて、必要な仕様が変わる度にそれを伝えたら都度欲しいものができた。成果物は<a href="https://github.com/k0kubun/ruby/blob/9f4c9f741de5581ba4bee3602f3b8869c666824a/misc/yjit_perf.py">これ</a>。</p> <h2 id="自分が詳しくない環境を扱わせる">自分が詳しくない環境を扱わせる</h2> <p>僕は私用にはLinuxを使い、仕事ではmacOSを使わされているのだが、Windowsはあまり触らないため詳しくない。ruby/rubyのCIでVisual Studio 2019上でVisual Studio 2015相当のC言語環境をセットアップする必要があったのだが、まるでやり方がわからなかったので、当時使っていたGitHub ActionsのYAMLを貼り付け、<a href="https://github.com/ruby/ruby/pull/9452">書き直してもらった</a>。</p> <p>例えば <code>vcvars64.bat -vcvars_ver=14.0</code> と書くとVisual Studio 2015相当で、その結果 C/C++ Optimizing Compiler Version 19.00.24247.2と出たら2015で、19.29.30153だと2019なのだが、こんなわけのわからないバージョンスキームを採用しているWindows環境を理解するのは人類には不可能なので、AIにやらせると良い。</p> <p>他には、会社のKubernetes環境で特定のラベルを持つPodを探して中に入る必要あったのだが、Kubernetesを採用していないインフラを触る期間が続いたため全然使い方がわからず、一連のコマンドをAIに書かせたりした。エラーにも遭遇したが、エラーを貼りつけたらAIがデバッグしてくれた。 Kubernetesも人類には難しすぎるので、AIに使わせると良い。</p> <h1 id="自分でやった方がいいケース">自分でやった方がいいケース</h1> <h2 id="必要な入力が大きい">必要な入力が大きい</h2> <p>僕がLLMを使う時は基本的にChatGPT (GPT-4) を使っているのだが、インターネット上のこのファイルを読んでくれとか、コンテキストに収まらないほどでかいファイルを貼り付けてこれを読んでくれみたいなのは少なくともデフォルトのチャット画面からはできないので、ChatGPTに渡す情報量がある程度小さくないとワークしない。</p> <p>例えば膨大なRuby処理系のコードを読み込んでそこに最適化を実装するみたいな作業は、それを任せるのに必要なコンテキストが大きすぎて伝えるのが難しいので、自分でやっている。目的のコードに似た実装を持つ関数を1つ渡して書かせてみたこともあるが、自分で書いたヘルパー関数の定義なども渡さないと正しく使ってくれない。</p> <p>そういう状況だとGitHub Copilotの方がインターフェース的には向いてるような気がするが、なんというか所詮コード補完だなという感じの結果になることが多くて、AIに渡すコンテキストを自分でコントロールしないと、読んで欲しいところを読んでくれてない感じになる。</p> <h2 id="大体書けていて細かい手直しだけ必要">大体書けていて細かい手直しだけ必要</h2> <p>チャットでAIにコードを書いてもらうと、何か修正が必要になった時に全て書き直しになるため、コードが長ければ長いほど再生成に時間がかかる。何十行もあるコードで、自明な変更を一行足すくらいだと、AIにやらせる方がかえって生産性が低くなる。</p> <p>また、何度もやり取りを繰り返すと、それ自体大きなコンテキストになってしまい、最初の方に言ったことを忘れてしまう。これ忘れとるやんけ、と伝えると、その前に伝えた別のことを忘れてきたりする。ある程度できてきて簡単な修正で完成する状態になったら、人間がやってしまった方がいいこともある。</p> <h1 id="まとめ">まとめ</h1> <p>いかがでしたか? 人類はまだ失職できないことがわかりました!</p> k0kubun 2023年にやったこと hatenablog://entry/6801883189070988025 2023-12-31T15:10:09+09:00 2023-12-31T15:11:52+09:00 今年で30歳、社会人9年目、在米5年目になった。今年は 趣味でRJITを作り、仕事でYJITを超高速化した 初めて論文を国際会議に投稿し、採択された 子供とプリスクールに行き始めた という感じの一年だった。 仕事 大変ありがたいことに、自分が今一番興味のある仕事であるYJITの高速化に集中できた一年だった。 いろいろやったが、代表作は以下の三つかなと思う。 スタックオペランドのレジスタアロケータ 最適化未対応なメソッド呼び出しのフォールバック 例外ハンドラのコンパイル どれもベンチマークがかなり速くなった。 特に二つ目と三つ目は、自分で発案してかつ主に僕が重要性を訴えていた奴で、 それらで大き… <p>今年で30歳、社会人9年目、在米5年目になった。今年は</p> <ul> <li>趣味でRJITを作り、仕事でYJITを超高速化した</li> <li>初めて論文を国際会議に投稿し、採択された</li> <li>子供とプリスクールに行き始めた</li> </ul> <p>という感じの一年だった。</p> <h2 id="仕事">仕事</h2> <p>大変ありがたいことに、自分が今一番興味のある仕事であるYJITの高速化に集中できた一年だった。 いろいろやったが、代表作は以下の三つかなと思う。</p> <ul> <li><a href="https://github.com/ruby/ruby/pull/7651">スタックオペランドのレジスタアロケータ</a></li> <li><a href="https://github.com/ruby/ruby/pull/8106">最適化未対応なメソッド呼び出しのフォールバック</a></li> <li><a href="https://github.com/ruby/ruby/pull/8171">例外ハンドラのコンパイル</a></li> </ul> <p>どれもベンチマークがかなり速くなった。 特に二つ目と三つ目は、自分で発案してかつ主に僕が重要性を訴えていた奴で、 それらで大きな成果が出たときはかなり達成感があった。 単独のPRでRailsベンチが7%速くなった時はこりゃ昇給するわと思ったが、実際めちゃくちゃ昇給した。</p> <p>ベンチマークも速くしている一方、僕は本番アプリの最適化を主戦場にしていて、 最適化のヒントになるメトリクスをひたすら追加し、 毎週のようにRuby masterを本番にデプロイし、効果を計測することを繰り返した。 Ruby 3.2ではYJITによる高速化が10%程度だったのが、 Ruby 3.3では弊社最大サイズのアプリ(モノリス)と最大トラフィックのアプリ(StoreFront Renderer)がどちらも YJITで17-18%くらい高速化する状態になった。 チーム全体での成果であるが、上記の変更は目に見えて効果があった。</p> <h2 id="論文">論文</h2> <p>YJITに関する論文を業務で書き、<a href="https://2023.splashcon.org/home/mplr-2023">MPLR</a>という査読付きカンファレンスで採択された。</p> <ul> <li><a href="https://dl.acm.org/doi/10.1145/3617651.3622982">Evaluating YJIT’s Performance in a Production Context: A Pragmatic Approach</a></li> </ul> <p>僕は去年修士を卒業したばかりで、在学中に論文形式のものは何本も書いたのだが、 そもそも修士論文なしで卒業するプログラムなこともあり、論文をどこかに投稿するようなことはなかった。 チーム内にYJITの作者がいるため僕はファーストオーサーではなかったが、 執筆的にも論文のトピック的にもそこそこ貢献したため、セカンドオーサーであった。 学士でも論文を投稿することはなかったので、これが初めての論文投稿経験となった。</p> <p>修士で取った授業のうち一つは研究の仕方そのものや論文の書き方を学ぶためのものだったので、 論文の執筆には少なからず興味があったし、個人の時間で書くほどの余裕はなかったので、業務で経験できて良かった。 ポルトガルでのカンファレンスだったが、学部時代にお世話になった先生にばったり会ってご挨拶できたのも良かった。</p> <h2 id="子供">子供</h2> <p>子供が三歳になり、プリスクールに行き始めた。 三歳だとオムツが外れてないといけないプリスクールがほとんどで、 娘はまだオムツをしていることにより選択肢が限られているのと、 あと単純に費用が安いので、Co-Opのプリスクールを選んだ。 Co-Opというのは親参加型の奴のことで、当番制でお手伝いをすることになっている。</p> <p>月に一回有給を取って子供と一緒にプリスクールに登園してそのジョブをやっている。 あと不定期に資金調達のためのイベントが行われいて、その手伝いもやっているし、 休日の午前を使って大掃除するのも何回かやっている。 プリスクールに行き始めれば子供を預けられる時間ができると最初は考えていたが、 子供が一人で登園するのを嫌がるため常に妻か僕が一緒に行っていて、 今のところ育児の負担はむしろ増えている。</p> <h2 id="資産">資産</h2> <p>僕のポートフォリオは<a href="https://www.bogleheads.org/wiki/Three-fund_portfolio">Three-fund portfolio</a>という奴で、 資産のほとんどをUS株72%、(US以外)全世界株18%、US債券10%で持つ状態を3年くらい維持している。 US株以外の資産は去年の下がりをようやく取り戻したくらいの状態だが、US株が好調なのでトータルではものすごくプラスになっている。 巷ではいわゆる<a href="https://emaxis.jp/fund/253425.html">オルカン</a>が流行っているが、 これもUS株を60%持つインデックスなので良い利益が出るんじゃないだろうか。</p> <p>USでは総資産が$2M (2億8000万円) 以上あるとグリーンカードを放棄する時にExit Taxという税金が取られることになっていて、 今はその半分くらいまで進捗したのだが、 僕は全資産に対して何割か課税されるという勘違いをしていたのでこれまで結構ビビっており、 $2Mに達する前に日本に本帰国するのを検討していた。 よく調べてみると、実際には資産ではなく未確定のキャピタルゲインに対して課税されるということだった。 自分が覚悟していたほどは課税されなそうなので、帰国は完全に家族の都合だけ見て決めればいいなと思った。</p> <h2 id="散財">散財</h2> <h3 id="テスラ">テスラ</h3> <p>ここ数年値上げを続けていたテスラの値段が、電気自動車の税制優遇の関係で今年何度か下がった。 一番最初に大きく下げた直後に、中古の2015 Mazda 3から新車の2023 Tesla Model 3 RWD ($43,990) に買い替えた。 僕は自動運転が欲しくて買っていて、普段は無課金のAutopilotを酷使し、連休中の現在は一時的にFull Self-Driving (月額$199) を試しているのだが、どちらも便利だし、乗り心地も良い。 妻も満足しているようでよかった。</p> <h3 id="歯科矯正">歯科矯正</h3> <p>アメリカのママ友に歯並びの良い人が多いようで、妻が歯科矯正をやり始めた。 僕はあまり興味はなかったのだが、妻がやって欲しいと言っていたのと、 歯並びが良い方が歯磨きがしやすくなるという話に説得され、僕もやり始めた。 一人 $5,000 以上かかっていて高いし痛いのだが、終わったらどうなるのかは楽しみである。</p> <h2 id="登壇">登壇</h2> <p>以下の2回登壇した。 今年は社会人になってから最も登壇数が少ない一年だった。 リモート登壇はもう少し自分から応募するなどしても良かった気がするが、 物理参加枠はRuby Infraチームでニューヨークに集まった奴と、YJIT論文でポルトガルに行っていた分で家族に負担をかけたので、 これが限界と思われる。</p> <ul> <li><a href="https://speakerdeck.com/k0kubun/rubykaigi-2023">RubyKaigi 2023: Ruby JIT Hacking Guide</a></li> <li><a href="https://findy.connpass.com/event/289394/">Aaronさんとk0kubunさんに聞く!YJITを用いたShopify開発環境と海外アーキテクチャ</a></li> </ul> <p>ポッドキャストでは初めて<a href="https://www.remoteruby.com/">Remote Ruby</a>に出させてもらった。 同僚が結構出ているシリーズなので、入社したころに結構聴いたのだが、自分も出れて良かった。</p> <ul> <li><a href="https://www.remoteruby.com/2260490/13760916-optimizing-ruby-jit-compilers-with-takashi-kokubun">Optimizing Ruby JIT Compilers with Takashi Kokubun</a></li> </ul> <h2 id="ブログ">ブログ</h2> <p>今年は日本語では9記事ほど書いた。 書きたいネタを思いついた時に衝動的に書いていたのだが、 おおむね例年くらいのペースで投稿し、ブクマもそこそこ集まった。 どれも楽しく書けたので、そういう感じで続けたい。</p> <ul> <li><a href="https://k0kubun.hatenablog.com/entry/12x-salary">&#x30A8;&#x30F3;&#x30B8;&#x30CB;&#x30A2;&#x304C;&#x7D66;&#x6599;&#x3092;12&#x500D;&#x306B;&#x3059;&#x308B;&#x65B9;&#x6CD5; - k0kubun&#39;s blog</a><a href="https://b.hatena.ne.jp/entry/https://k0kubun.hatenablog.com/entry/12x-salary" class="http-bookmark"><img src="https://b.hatena.ne.jp/entry/image/https://k0kubun.hatenablog.com/entry/12x-salary" alt="" class="http-bookmark" /></a></li> <li><a href="https://k0kubun.hatenablog.com/entry/mojo">Mojo&#x306F;&#x300C;C&#x8A00;&#x8A9E;&#x306E;&#x3088;&#x3046;&#x306B;&#x901F;&#x3044;Python&#x300D;&#x306A;&#x306E;&#x304B; - k0kubun&#39;s blog</a><a href="https://b.hatena.ne.jp/entry/https://k0kubun.hatenablog.com/entry/mojo" class="http-bookmark"><img src="https://b.hatena.ne.jp/entry/image/https://k0kubun.hatenablog.com/entry/mojo" alt="" class="http-bookmark" /></a></li> <li><a href="https://k0kubun.hatenablog.com/entry/pc-2023">&#x81EA;&#x4F5C;PC2023: Ryzen&#x3092;&#x3084;&#x3081;&#x305F; - k0kubun&#39;s blog</a><a href="https://b.hatena.ne.jp/entry/https://k0kubun.hatenablog.com/entry/pc-2023" class="http-bookmark"><img src="https://b.hatena.ne.jp/entry/image/https://k0kubun.hatenablog.com/entry/pc-2023" alt="" class="http-bookmark" /></a></li> <li><a href="https://k0kubun.hatenablog.com/entry/oss-against-the-world">Re: OSS&#x3067;&#x4E16;&#x754C;&#x3068;&#x6226;&#x3046;&#x305F;&#x3081;&#x306B; - k0kubun&#39;s blog</a><a href="https://b.hatena.ne.jp/entry/https://k0kubun.hatenablog.com/entry/oss-against-the-world" class="http-bookmark"><img src="https://b.hatena.ne.jp/entry/image/https://k0kubun.hatenablog.com/entry/oss-against-the-world" alt="" class="http-bookmark" /></a></li> <li><a href="https://qiita.com/k0kubun/items/766dc15773ec73925163">Rust&#x30D7;&#x30ED;&#x30B0;&#x30E9;&#x30E0;&#x306E;&#x30C7;&#x30D0;&#x30C3;&#x30B0;&#x8F9B;&#x3059;&#x304E;&#x554F;&#x984C; #Rust - Qiita</a><a href="https://b.hatena.ne.jp/entry/https://qiita.com/k0kubun/items/766dc15773ec73925163" class="http-bookmark"><img src="https://b.hatena.ne.jp/entry/image/https://qiita.com/k0kubun/items/766dc15773ec73925163" alt="" class="http-bookmark" /></a></li> <li><a href="https://k0kubun.hatenablog.com/entry/ruby-3-3-yjit">Ruby 3.3&#x3067;YJIT&#x3092;&#x4ECA;&#x3059;&#x3050;&#x6709;&#x52B9;&#x306B;&#x3059;&#x3079;&#x304D;&#x7406;&#x7531; - k0kubun&#39;s blog</a><a href="https://b.hatena.ne.jp/entry/https://k0kubun.hatenablog.com/entry/ruby-3-3-yjit" class="http-bookmark"><img src="https://b.hatena.ne.jp/entry/image/https://k0kubun.hatenablog.com/entry/ruby-3-3-yjit" alt="" class="http-bookmark" /></a></li> <li><a href="https://k0kubun.hatenablog.com/entry/tuning-yjit">YJIT&#x306E;&#x6027;&#x80FD;&#x3092;&#x6700;&#x5927;&#x9650;&#x5F15;&#x304D;&#x51FA;&#x3059;&#x65B9;&#x6CD5; - k0kubun&#39;s blog</a><a href="https://b.hatena.ne.jp/entry/https://k0kubun.hatenablog.com/entry/tuning-yjit" class="http-bookmark"><img src="https://b.hatena.ne.jp/entry/image/https://k0kubun.hatenablog.com/entry/tuning-yjit" alt="" class="http-bookmark" /></a></li> <li><a href="https://k0kubun.hatenablog.com/entry/rjit">RJIT: Ruby&#x3067;Ruby&#x306E;JIT&#x30B3;&#x30F3;&#x30D1;&#x30A4;&#x30E9;&#x3092;&#x66F8;&#x3044;&#x305F; - k0kubun&#39;s blog</a><a href="https://b.hatena.ne.jp/entry/https://k0kubun.hatenablog.com/entry/rjit" class="http-bookmark"><img src="https://b.hatena.ne.jp/entry/image/https://k0kubun.hatenablog.com/entry/rjit" alt="" class="http-bookmark" /></a></li> <li><a href="https://k0kubun.hatenablog.com/entry/2023/05/18/171546">RubyKaigi&#x3067;JIT&#x30B3;&#x30F3;&#x30D1;&#x30A4;&#x30E9;&#x306E;&#x66F8;&#x304D;&#x65B9;&#x306B;&#x3064;&#x3044;&#x3066;&#x767A;&#x8868;&#x3057;&#x305F; - k0kubun&#39;s blog</a><a href="https://b.hatena.ne.jp/entry/https://k0kubun.hatenablog.com/entry/2023/05/18/171546" class="http-bookmark"><img src="https://b.hatena.ne.jp/entry/image/https://k0kubun.hatenablog.com/entry/2023/05/18/171546" alt="" class="http-bookmark" /></a></li> </ul> <p>Hacker News上でアクティブな同僚が多いので僕もHacker Newsのフロントページに乗るかどうかということを気にするようになったが、 英語で投稿したものは2回ほどランクインし、英語圏でランキングを上げる経験も積めるようになってきた。</p> <ul> <li><a href="https://news.ycombinator.com/item?id=35054163">RJIT, a new JIT for Ruby</a> (336 points, <a href="https://hnrankings.info/35054163/">2位</a>)</li> <li><a href="https://news.ycombinator.com/item?id=37579926">Ruby 3.3's YJIT Runs Shopify's Production Code 15% Faster</a> (175 points, <a href="https://hnrankings.info/37579926/">2位</a>)</li> </ul> <h2 id="OSS活動">OSS活動</h2> <h3 id="RJIT">RJIT</h3> <p>今年の新作は<a href="https://github.com/ruby/ruby/pull/7448">RJIT</a>だけである。 最初いくつかのベンチマークでYJITを抜いてしまった結果、 YJITを仕事にしている都合これはconflict of interestになり得ると言われたり、 RJITの話ばかりしているのがお気に召さなかったのかTwitterでリムーブされたりしたため、 その辺を丸く収めるべく、出した直後は意識的に開発速度を落としていた。 とはいえ、やりたいことはいろいろあるプロジェクトなので、来年もほどほどのペースでいろいろやれたらいいなと思う。</p> <p>RJITとYJITを両方開発していた関係で、 今年は<a href="https://speakerdeck.com/k0kubun/rubykaigi-2023?slide=3">過去1年間のコミット数がnobuさんを超えた瞬間</a>もあったのだが、 上記のRJITの件と、論文執筆やリリース前のバグ修正で失速し、 Ruby 3.3も<a href="https://github.com/ruby/ruby/graphs/contributors?from=2022-12-26&amp;to=2023-12-25&amp;type=c">nobuさんの方がコミットが多かった</a>。 nobuさんはすごい。</p> <h3 id="sqldef-xremap">sqldef, xremap</h3> <p>去年に引き続き、 個人でやってるOSSでは<a href="https://github.com/sqldef/sqldef">sqldef</a>と<a href="https://github.com/k0kubun/xremap">xremap</a>が一番盛り上がっている。</p> <p>sqldefはmssqldefで<a href="https://github.com/odz">@odz</a>さん、psqldefで<a href="https://github.com/hokaccha">@hokaccha</a>さんが新たにメンテナに就任し、 大変心強い。メンテナ5人体制になったので、 リポジトリも個人アカウント下からsqldef orgに移管し<a href="https://github.com/sqldef/sqldef">sqldef/sqldef</a>となった。</p> <p>xremapもスターが☆1,000を超えた。mrubyで書いていたころはhanachinさんもメンテナだったが、 Rustに書き換えてからずっと僕だけでメンテしている。 普段のissueのやり取りでも、sqldefはGoだから皆書いてくれるが、xremapはRustなので書けないと言われることが多い。 正直sqldefもRustで書き直してenumやパターンマッチを使ったりしたいのだが、 人類のほとんどはRustを書きたがらないため、sqldefの方はGoのままにしておくか…という気持ちである。 「は? Rust書くの簡単やろがい」と思った人には、xremapの共同メンテナとして無双していただければと思う。</p> <h2 id="2024年は">2024年は</h2> <p>今年はYJITが大幅に速くなるアイデアを運良く複数思いついたが、 来年はそれに再現性を持たせられるようにして、 誰も想像していなかったような方法でYJITを無限に速くし、無限にお金を稼ぎたいと思う。</p> <h2 id="過去ログ">過去ログ</h2> <ul> <li><a href="https://k0kubun.hatenablog.com/entry/2022-summary">2022年にやったこと</a></li> <li><a href="https://k0kubun.hatenablog.com/entry/2021-summary">2021年にやったこと</a></li> <li><a href="https://k0kubun.hatenablog.com/entry/2020-summary">2020年にやったこと</a></li> <li><a href="https://k0kubun.hatenablog.com/entry/2019-summary">2019年にやったこと</a></li> <li><a href="https://k0kubun.hatenablog.com/entry/2018-summary">2018年にやったこと</a></li> <li><a href="https://k0kubun.hatenablog.com/entry/2017-summary">2017年にやったこと</a></li> <li><a href="https://k0kubun.hatenablog.com/entry/2016-summary">2016年にやったこと</a></li> <li><a href="https://k0kubun.hatenablog.com/entry/2015/12/31/000052">2015年にやったこと</a></li> </ul> k0kubun Ruby 3.3でYJITを今すぐ有効にすべき理由 hatenablog://entry/6801883189070150889 2023-12-27T15:23:57+09:00 2023-12-28T12:59:35+09:00 Ruby 3.3がリリースされた。YJITには非常に多くの改善が含まれたリリースだったが、 NEWS解説記事やリリースパーティーでは 2点しか触れられなかったので、この記事ではRuby 3.3でYJITがどう改善されたかについて解説する。 YJITは既に実用段階 YJITはRuby 3.1で導入されたが、Ruby 3.2の時点でexperimentalのマークが外れ、実用段階となった。 Ruby 3.2では、以下のような企業で性能改善が報告された。 DeNA: 40% 高速化 GMOペバボ: 18% 高速化 STORES: 6.5-7.5% 高速化 Timee: 10% 高速化 メドピア: 2… <p>Ruby 3.3がリリースされた。YJITには非常に多くの改善が含まれたリリースだったが、 <a href="https://product.st.inc/entry/2023/12/25/160504">NEWS解説記事</a>や<a href="https://andpad.connpass.com/event/302363/">リリースパーティー</a>では 2点しか触れられなかったので、この記事ではRuby 3.3でYJITがどう改善されたかについて解説する。</p> <h1 id="YJITは既に実用段階">YJITは既に実用段階</h1> <p>YJITはRuby 3.1で導入されたが、Ruby 3.2の時点でexperimentalのマークが外れ、実用段階となった。 Ruby 3.2では、以下のような企業で性能改善が報告された。</p> <ul> <li>DeNA: <a href="https://engineering.dena.com/blog/2023/12/voice-pococha-yjit/">40% 高速化</a></li> <li>GMOペバボ: <a href="https://shimoju.jp/2023/08/10/ruby-3-2-yjit-with-rails-6-1/">18% 高速化</a></li> <li>STORES: <a href="https://product.st.inc/entry/2023/05/31/130809">6.5-7.5% 高速化</a></li> <li>Timee: <a href="https://tech.timee.co.jp/entry/2023/05/10/133000">10% 高速化</a></li> <li>メドピア: <a href="https://tech.medpeer.co.jp/entry/2023/05/09/100000">2.8% 高速化</a></li> <li>BOOK☆WALKER: <a href="https://developers.bookwalker.jp/entry/2023/01/25/114710">20-30% 高速化</a></li> <li>Discourse: <a href="https://blog.discourse.org/2023/05/running-ruby-3-2s-yjit-in-production-at-discourse/">15.8-19.6% 高速化</a></li> <li>Lobsters: <a href="https://lobste.rs/s/m9ivcf/we_turned_lobste_rs_into_rails_benchmark#c_fkud5w">26% 高速化</a></li> <li>CompanyCam: <a href="https://ruby.social/@mcphat/111075935007519631">20-40% 高速化</a></li> </ul> <p>弊社Shopifyで最もトラフィックが多いアプリでは、 Ruby 3.2の時点でのYJITによる高速化は<a href="https://twitter.com/paracycle/status/1605706245955997697">10%程度</a>だったが、 Ruby 3.3では<a href="https://railsatscale.com/2023-12-04-ruby-3-3-s-yjit-faster-while-using-less-memory/">17%高速化</a>まで改善した。 YJITを本番で使っている全ての人にRuby 3.3へのバージョンアップをお勧めしたい。</p> <p>我々はRuby 3.3.0のリリースを安定化させるべく、リリース前からRuby masterを本番のモノリスに全台デプロイしていた。 現在はリリース版Ruby 3.3.0が走っており、YJITも有効になっているが、Ruby masterを使っていた段階で数多くのバグを弊社が発見・修正したため、 Ruby 3.3.0は比較的安定したリリースになっているはずである。</p> <h1 id="YJIT本番運用のための手引き">YJIT本番運用のための手引き</h1> <p>ここまで読んで「YJIT使うぞ!」となって使ってみたが思うように性能が改善しなかった人のために、 本番運用のためのドキュメントへのリンクを貼っておく。</p> <ul> <li>Ruby 3.2 <ul> <li><a href="https://github.com/ruby/ruby/blob/ruby_3_2/doc/yjit/yjit.md#performance-tips-for-production-deployments">Performance Tips for Production Deployments</a></li> <li><a href="https://github.com/ruby/ruby/blob/ruby_3_2/doc/yjit/yjit.md#saving-yjit-memory-usage">Saving YJIT Memory Usage</a></li> </ul> </li> <li>Ruby 3.3 <ul> <li><a href="https://github.com/ruby/ruby/blob/ruby_3_3/doc/yjit/yjit.md#performance-tips-for-production-deployments">Performance Tips for Production Deployments</a></li> <li><a href="https://github.com/ruby/ruby/blob/ruby_3_3/doc/yjit/yjit.md#reducing-yjit-memory-usage">Saving YJIT Memory Usage</a></li> </ul> </li> </ul> <p>Ruby 3.3で本番運用に便利なツールが増えたため、バージョンごとに少し内容の異なるドキュメントを管理している。 Ruby 3.2時点での日本語の記事としては <a href="https://k0kubun.hatenablog.com/entry/tuning-yjit">YJITの性能を最大限引き出す方法</a> がある。 Ruby 3.3で便利になった点は以下で解説する。</p> <h1 id="Ruby-33のYJIT改善点">Ruby 3.3のYJIT改善点</h1> <p>前置きが長くなったが、ここからNEWSで触れられている改善点について解説していく。 運用方法に影響がある点から順に書いていく。</p> <h2 id="Code-GCのデフォルト無効化">Code GCのデフォルト無効化</h2> <p>YJITが生成するコード量は <code>--yjit-exec-mem-size</code> でコントロールできる (デフォルト64MiB)。 生成コードのサイズが <code>--yjit-exec-mem-size</code> に達すると、YJITはデフォルトで以下のような動きをする。</p> <ul> <li>Ruby 3.2: 全ての生成コードを破棄し、以降呼ばれたメソッドをコンパイルし直す。</li> <li>Ruby 3.3: 新たにメソッドをコンパイルしなくなる。未コンパイルのメソッドはインタプリタ実行される。</li> </ul> <p>Ruby 3.2のこの挙動をCode GCと呼んでいる。 数時間に一回Code GCが走る程度なら大した性能影響はないのだが、 <code>--yjit-exec-mem-size</code> が小さすぎると、頻繁にコンパイルし直すコストによってアプリがむしろ遅くなる場合がある。</p> <p>こういった問題にヒットしにくくなるよう、Code GCはデフォルトで無効になった。 これの最大の利点は気軽に <code>--yjit-exec-mem-size</code> が下げられるようになった点で、 <code>RubyVM::YJIT.runtime_stats[:code_region_size]</code> を参考にしつつ、 <code>--yjit-exec-mem-size=32</code> のような設定を使うのが現実的な選択肢になった。</p> <p>もう一つの利点に<a href="https://ja.wikipedia.org/wiki/%E3%82%B3%E3%83%94%E3%83%BC%E3%82%AA%E3%83%B3%E3%83%A9%E3%82%A4%E3%83%88">Copy on Write</a> フレンドリになる点がある。 弊社ではモダンなUnicornフォークである<a href="https://github.com/Shopify/pitchfork">Pitchfork</a>を使っているが、 これは既にリクエストを捌いているワーカーを定期的にフォークし直すことでプロセス間のメモリ共有を目指すリフォーキングという機能が備わっている。 リフォーク対象のサーバーが既にYJITのコンパイルを停止済みなら、 YJITが使うメモリは全ワーカー間で共有し続けられることになる。</p> <h2 id="RubyVMYJITenable-の追加">RubyVM::YJIT.enable の追加</h2> <p>YJITはこれまでコマンドライン引数 <code>--yjit</code> や環境変数 <code>RUBY_YJIT_ENABLE=1</code> で有効化するしかなかったが、 それらを使わずとも、Rubyコード内で <code>RubyVM::YJIT.enable</code> を呼び出すだけでYJITが有効化できるようになった。</p> <p>開発中のRails 7.2ではこれを呼び出すイニシャライザが<a href="https://github.com/rails/rails/pull/49947">デフォルトで生成されるようになった</a>。 つまりRailsではこれを使ってYJITがデフォルト化されたということになる。</p> <p>もう一つの利点は、YJITの起動を遅延させることで、 アプリ初期化後は使われないコードのコンパイルを避けメモリ消費量を削減できる点である。 Railsのイニシャライザでも効果はあるが、理想的にはUnicornの<code>after_fork</code>やPumaの<code>after_worker_fork</code>から呼び出すと良い。 これにより、起動するワーカーの半分だけYJITを有効化し、インタプリタと性能を比較する基盤として利用することもできる。</p> <p>なお、<code>--yjit-exec-mem-size</code> などのチューニングオプションも指定するだけでも起動時にYJITが有効化されるため、 その場合も遅延起動するには <code>--yjit-disable</code> を明示する必要がある。</p> <h2 id="一部YJIT-statsのデフォルト提供">一部YJIT statsのデフォルト提供</h2> <p><code>RubyVM::YJIT.runtime_stats[:yjit_alloc_size]</code> がデフォルトで提供されるようになった。 これはYJITがRustのヒープにアロケートしているメタデータのサイズで、<code>:code_region_size</code> と合わせると、 YJITが使っているメモリをバイト単位で監視できる。 YJITを運用する際は、この2つだけでも見ておくと <code>--yjit-exec-mem-size</code> のチューニングの参考になる。</p> <p>また、<code>RubyVM::YJIT.runtime_stats[:ratio_in_yjit]</code> が <code>--yjit-stats</code> 時にデフォルトのビルドでも提供されるようになった。 これはRuby VM上で実行される命令のうち何%がYJITで実行されたかを示すもので、 理想的には最大99%くらいが望ましいが、アプリによってはこれが平均90%とかでも18%高速化したりする。 速度を妥協して <code>--yjit-exec-mem-size</code> を下げる場合は、これがあまり下がり過ぎないように気をつけると良い<a href="#f-31bbbc55" id="fn-31bbbc55" name="fn-31bbbc55" title="--yjit-stats のかわりに RubyVM::YJIT.enable(stats: true) でもstatsが有効化できるので、これを使ってPumaやUnicornのワーカーのうち1つだけstatsを有効にしておくと、比較的楽にratio_in_yjitが監視できて便利かもしれない。">*1</a>。</p> <p>NEWSにはないが <code>RubyVM::YJIT.runtime_stats[:compile_time_ms]</code> も追加されており、デフォルトで使える。 これはYJITがコンパイルに使った累計時間を出すもので、例えばリクエスト前後で呼んで差を取ると、 そのリクエストでのYJITのコンパイルのオーバーヘッドを見ることができる。<code>GC.stat(:time)</code> に似ている。</p> <h2 id="YJITのメモリ使用量の削減">YJITのメモリ使用量の削減</h2> <p>Ruby 3.2の時点で<a href="https://qiita.com/k0kubun/items/0925afa44da13649a1a0">Rustの省メモリ化</a>の努力はあったが、 Ruby 3.3でもRcのかわりにBoxを使ったり、ひとつのu8に様々な意味のビットを詰めまくるといったチューニングが行なわれ、 YJITが使うメタデータのサイズは大幅に小さくなった。 Ruby 3.2とRuby 3.3で <code>:code_region_size</code> が同じ程度であれば、<code>:yjit_alloc_size</code> にあたる部分は大きく削減されるはずである。</p> <p>それから、<code>--yjit-cold-threshold</code> という概念が追加され、あまり使われないメソッドのコンパイルをスキップするようになった。 また、<code>--yjit-call-threshold</code> がデフォルトで30なのが、メソッドやブロックが4万以上あると120に自動で引き上げられるようになった。 これにより、コンパイルしてもあまり性能に貢献しないメソッドがコンパイルされなくなり、メモリ使用量が節約される。</p> <h2 id="高速化">高速化</h2> <p>Ruby 3.2の時点では、YJITがコンパイルに対応していないパスがそこそこあり、 <code>--yjit-exec-mem-size</code> が十分でも <code>:ratio_in_yjit</code> が90%程度に留まることがあった。 記事が長くなってしまったので詳細は別の機会に語るが、 Ruby 3.3ではこれらの問題をほぼ解決し、ほとんどのアプリで <code>:ratio_in_yjit</code> が99%に達するようになった。 Ruby 3.2だと運悪くYJITの対応率が低かったアプリでも、Ruby 3.3なら速くなることが期待できる。</p> <p>あとは、特別な最適化が実装されたCメソッドの数が増えており、 <a href="https://github.com/ruby/ruby/blob/v3_3_0/NEWS.md#yjit">NEWS</a>で言及している奴のことだが、 それらはインライン化もされる。 また、単に即値を返すRubyメソッドのインライン化も実装され、具体的にはRailsの<code>blank?</code>とかが<code>mov</code>命令一発になるのだが、 <code>present?</code>の方もRails 7.2では<a href="https://github.com/rails/rails/pull/49909">同じ最適化が期待できるようになった</a>。</p> <h1 id="まとめ">まとめ</h1> <p>あなたとYJIT、今すぐ <code>RUBY_YJIT_ENABLE=1</code></p> <h1 id="参考文献">参考文献</h1> <ul> <li><a href="https://railsatscale.com/2023-09-18-ruby-3-3-s-yjit-runs-shopify-s-production-code-15-faster/">Ruby 3.3's YJIT Runs Shopify's Production Code 15% Faster</a></li> <li><a href="https://railsatscale.com/2023-11-07-yjit-is-the-most-memory-efficient-ruby-jit/">YJIT Is the Most Memory-Efficient Ruby JIT</a></li> <li><a href="https://railsatscale.com/2023-12-04-ruby-3-3-s-yjit-faster-while-using-less-memory/">Ruby 3.3's YJIT: Faster While Using Less Memory</a></li> </ul> <div class="footnote"> <p class="footnote"><a href="#fn-31bbbc55" id="f-31bbbc55" name="f-31bbbc55" class="footnote-number">*1</a><span class="footnote-delimiter">:</span><span class="footnote-text">--yjit-stats のかわりに RubyVM::YJIT.enable(stats: true) でもstatsが有効化できるので、これを使ってPumaやUnicornのワーカーのうち1つだけstatsを有効にしておくと、比較的楽にratio_in_yjitが監視できて便利かもしれない。</span></p> </div> k0kubun エンジニアが給料を12倍にする方法 hatenablog://entry/6801883189059328996 2023-11-16T20:30:25+09:00 2023-11-16T20:32:30+09:00 はてブの人気エントリーに日本のエンジニア達は海外に出なければいけないという記事があった。 カナダ在住で経験年数4年のソフトウェアエンジニアで年収1600万円の方らしく、 日本より海外の方がソフトウェアエンジニアの給料が一般に高いので海外に行くべきという話が書かれている。 実際僕も居住地域による給与差を利用すべく渡米し、先月の記事 では新卒から数えて8年で年収が12倍になっていた話も紹介した。 一方、年収1600万円であれば海外に出なくても稼げると思っているので、 国内にいてもできそうなものも含め、ソフトウェアエンジニアとして給料を上げる上で過去に活用したハックを紹介していきたい。 昇給履歴 新… <p>はてブの人気エントリーに<a href="https://note.com/kei726/n/nc674049f61f8">日本のエンジニア達は海外に出なければいけない</a>という記事があった。 カナダ在住で経験年数4年のソフトウェアエンジニアで年収1600万円の方らしく、 日本より海外の方がソフトウェアエンジニアの給料が一般に高いので海外に行くべきという話が書かれている。</p> <p>実際僕も居住地域による給与差を利用すべく渡米し、<a href="https://k0kubun.hatenablog.com/entry/pc-2023">先月の記事</a> では新卒から数えて8年で年収が12倍になっていた話も紹介した。 一方、年収1600万円であれば海外に出なくても稼げると思っているので、 国内にいてもできそうなものも含め、ソフトウェアエンジニアとして給料を上げる上で過去に活用したハックを紹介していきたい。</p> <h1 id="昇給履歴">昇給履歴</h1> <h2 id="新卒入社">新卒入社</h2> <p>僕が<a href="https://info.cookpad.com/">新卒で入社した会社</a>の当時の初年度給与は450万円だった (<a href="https://web.archive.org/web/20141213150608/http://recruit.cookpad.com/jobs/graduate_recruitment/">公開情報</a>)。 大学の4年間はずっとアルバイトとしてソフトウェアエンジニアをやっていて、 3社を渡り歩いて時給は800〜1350円という感じだったが、それに比べると正社員というのはすごい額の給料がもらえる。 経験年数というのはビザの取得とかにも影響してきたりするので、正社員にはさっさとなってしまうのが良い。</p> <h2 id="外資転職">外資転職</h2> <p>新卒社員として1年11か月働いた後、<a href="https://www.treasuredata.co.jp/about-jp/">外資の会社</a>に転職した。 東京のエンジニアポジションだと、この会社の最低年俸は800万円とかである (<a href="https://employment.en-japan.com/desc_989354/">公開情報</a>)。 新卒2年目の間に年収800万円に達していたら昇給RTAとしてはまあまあという感じがする。</p> <p>転職の前に<a href="https://job-draft.jp/">転職ドラフト</a>に参加していたのだが、 ありがたいことに外資ではなくともこれくらいの額の指名が結構いただけ、 1000万円で指名していただけた会社もあり、そのあたりを根拠にこの転職での給与を交渉した。</p> <p>外資なら、日本にいて<a href="https://www.estie.jp/blog/entry/2022/04/11/100000_1">年収2000万円の人</a>もざらにいるので、 年収1600万円は外資であれば日本でも割と有り得る話だと思う。</p> <h2 id="買収">買収</h2> <p>僕はこの会社にシリーズCの資金調達直後に入社したのだが、その1年後に会社が買収された。 この時社員からミリオネア (つまり1億円もらった人) が50人以上生まれたらしい (<a href="https://blog.allstarsaas.com/posts/treasure-data-journey">公開情報</a>) のだが、多分僕もそれにカウントされてそうな程度にはお金をいただいた。 この額がどう支払われたかは公開情報ではないが、買収後は4年間在籍してるわけで、 4年で1億円以上もらえてる場合の年収は…まあそういうことだ。</p> <p>有望そうなスタートアップを見つけたらなるべく早いうちに入っておくと、 日本でも一発で大金を得られるチャンスになるかもしれない。</p> <h2 id="渡米">渡米</h2> <p>買収で得られる収入はボーナスのようなもので、基本給にあたる部分は東京のエンジニアらしい推移を続けていたが、 渡米した段階で年収が増えて $151,491 になった (<a href="https://h1bdata.info/index.php?em=treasure+data&amp;job=senior+software+engineer&amp;city=&amp;year=2019">公開情報</a>)。 当時の為替で1600万円。アメリカの就労ビザであるH-1Bビザを申請する時、 給与は最低このくらいないといけないというガイドラインがあって、 僕の地域のSenior Software Engineerの当時のPrevailing Wageがこれであったと記憶している。 なので、シニアエンジニアがH-1BでSFベイエリアに渡米すると、最低でもこの年収はもらえることになる。 今の為替だと2200万円になる。</p> <p>僕の経験上、どこの会社でも従業員の現在の住所に従って給与には傾斜がかかる。 例えアメリカの会社に勤めていても、 例の記事の人のようにカナダ在住であればアメリカのNYやSFから勤めるのに比べたら給与は劣るはずだし、 日本からだとそれより更に低くなる。 逆に僕はカナダの会社にSFベイエリアから勤務しているが、多分カナダの本社周辺の人たちより良い傾斜がかかっている。</p> <p>つまりニューヨークかサンフランシスコに住みましょうという話になるのだが、 どっちも治安は最悪である。その点、サンフランシスコから少し南のシリコンバレーのあたりは、 田舎なので治安が少しマシで、給料はサンフランシスコより若干劣る程度で、日本食も豊富なのもあり、 いいバランスだなと思ってそこに住んでいる。</p> <h2 id="昇進">昇進</h2> <p>外資だと、マネージャーにならなくてもIndividual Contributorとしてそこそこ昇進し続けられるのが普通である。 Senior, Staff, Principal, Distinguished あたりが割とメジャーなタイトルで、 タイトルがインフレすると間にSenior StaffとかSenior Principalが挟まってくる。 目の前のタスクに集中するのではなく、多くのチームをまたいだデザインやリードをやるようにしていると、 タイトルが上がる。</p> <p>これらのタイトルはそれぞれ役割が異なるので、単に別の仕事として位置づけて給与に連動させない会社もあるが、 まあ普通はジョブタイトルごとに給与のレンジがあり、それは<a href="https://levels.fyi/">levels.fyi</a>を眺めればすぐにわかる。 なので、なるべくビジネスインパクトの大きいタイトルにポジションチェンジを続けると、ついでに給与も上がる。</p> <p>この会社では僕はStaffまで昇進した。 その際の給与交渉の額の参考にするために他の会社のリクルーターと話したりしていたが、 このタイトルでのSFベイエリアでのスタートアップの基本給の相場は $180,000 みたいな感じだった。 今の為替で2700万円。</p> <h2 id="大企業転職">大企業転職</h2> <p>この会社で2度目のEXITチャンスが見えてきて、 僕は<a href="https://twitter.com/k0kubun/status/1411140330175361031">2億円欲しい</a>と公言していた。 これは在籍し続ければ実現する可能性は十分にあったが、 <a href="https://findy-code.io/engineer-lab/compiler-k0kubun">コンパイラが書きたくなった</a>ので転職した。 それができる会社がたまたま社員1万人だっただけなのだが、 スタートアップから一転、上場済みの大企業に移ることとなった。</p> <p>スタートアップだと一発当てない限りは前述の $180,000 からそれほど年収が増えないイメージだが、 大企業だと2億円みたいな夢はないかわりに、安定して高い年収が得られる。 例えばAmazonのSeniorにあたるポジションは年収 $360,300 くらいらしい (<a href="https://www.levels.fyi/companies/amazon/salaries/software-engineer/levels/sde-iii">ソース: levels.fyi</a>) ので、大体倍くらいになるということ。 ちなみにこのポジションはリクルーターに話しかけられて受けたのだが、もらったオファーも実際そのくらいの額だった。 実際にはこのオファーは蹴ったわけだが、今の為替だと5400万円で、新卒の450万円の12倍ということになる。 円安じゃなかったとしても8倍はある。</p> <p>こういった相場感を適切に調べておき、複数の企業からオファーをもらっておくと、 このくらいの額がもらえるような交渉ができる。</p> <p>この辺は日本にいても当てはまる話で、例えばGoogleでSeniorまで昇進できた場合、 日本オフィスでも $265,266 (4000万円) とかもらえるようだ (<a href="https://www.levels.fyi/companies/google/salaries/software-engineer/levels/l5/locations/japan">ソース: levels.fyi</a>)。</p> <h1 id="QA">Q&amp;A</h1> <h2 id="お金に執着しすぎでは">お金に執着しすぎでは?</h2> <p>そう思う人は多分お金に困ったことがないのだろう。 学生時代に貯金を全て親の借金の返済に使われ、 大学院進学を<a href="https://k0kubun.hatenablog.com/entry/2015/02/19/012927">経済的理由により諦めた</a>といった経験から、 貧乏に対して常に強い不安を感じ続けている。 実家は家のローンの返済に苦労しているが、 自分の家族は家も教育も不自由なく得られるようにしたい。</p> <h2 id="起業した方が稼げるのでは">起業した方が稼げるのでは?</h2> <p>それがそんな簡単に上手くいくかはおいておいて、 僕は<a href="https://findy-code.io/engineer-lab/compiler-k0kubun">やっぱりコンパイラが書きたい</a>というのが最初にあって、 経営ではなくコードを書くのに集中できるロールのままお金もいっぱいもらえる状況を望んでいる。</p> <h2 id="海外だと物価も高いのでは">海外だと物価も高いのでは?</h2> <p>これはよくあるエアプコメントだと思う。例えば給料と出費が両方4倍になる時、手元に残るお金も4倍になることになる。 実際には、給料が12倍になった期間、例えば家賃はせいぜい4~5倍にしかなってないので、もっと残る。 僕の場合は老後は日本に帰るつもりなので、その残ったお金は低い物価の国で消費することになる。 もっと話を単純にすると、これくらい収入があると1年で数千万資産が増えるのだが、 日本にいたらそもそも額面で数千万受け取るのが大変だと思う。</p> <h2 id="海外だとレイオフされるのでは">海外だとレイオフされるのでは?</h2> <p>ビザの状況によっては割と深刻な問題だと思う。 僕の場合はもうグリーンカードを持っているのでそこは安心。これを書いた次の日にレイオフされるみたいなリスクはあるが、 普通は数ヶ月分給料がもらえるし、その間にまともな転職ができそうな程度にはリクルーティングメールは来続けてるので、 少なくとも金銭的な心配はない。個人的にレイオフされたら困るのは、自分がやりたい仕事ができなくなることくらいである。</p> <h1 id="まとめ">まとめ</h1> <p>海外に住むと、日本語は使えないし、趣味や食事や医療などの選択肢や治安などが変わってくる。 家庭がある場合は家族にも影響がある。</p> <p>「日本のエンジニア達は海外に出なければいけない」と結論づける前に、 海外に行くことで得られる給料が本当にその変化に見合うものなのか、 またそれは日本では達成できないものなのか考えておくと今後のためになる。</p> k0kubun Re: OSSで世界と戦うために hatenablog://entry/6801883189055490198 2023-11-02T17:27:47+09:00 2023-11-03T03:14:44+09:00 yusukebe さんの OSSで世界と戦うために を読んで感銘を受けた。 hono の快進撃もさることながら、OSSで日本のコミュニティの外にリーチしたり、 GitHubスター数を伸ばしたりみたいな話は、 自分も10年くらい挑戦し続けているけどあんまり表に出てこない気がするネタなので興奮した。 僕はいくつかの点で上記の記事とは違う方法でOSSで世界と戦っているのだが、 その中でうまく行っているものや、良くないと思っているものなどについて紹介したい。 GitHubのスター数 OSSを始めたばかりの学生時代、GitHubのスターへの執着がもはや煩悩の域であり、 集めたスターの数を合計するCLIツ… <p>yusukebe さんの <a href="https://yusukebe.com/posts/2023/oss-against-the-world/">OSSで世界と戦うために</a> を読んで感銘を受けた。 hono の快進撃もさることながら、OSSで日本のコミュニティの外にリーチしたり、 GitHubスター数を伸ばしたりみたいな話は、 自分も10年くらい挑戦し続けているけどあんまり表に出てこない気がするネタなので興奮した。</p> <p>僕はいくつかの点で上記の記事とは違う方法でOSSで世界と戦っているのだが、 その中でうまく行っているものや、良くないと思っているものなどについて紹介したい。</p> <h1 id="GitHubのスター数">GitHubのスター数</h1> <p>OSSを始めたばかりの学生時代、GitHubのスターへの執着がもはや煩悩の域であり、 集めたスターの数を合計する<a href="https://github.com/k0kubun/rockstar">CLIツール</a>を作ったり、 同じ計算方法でランキングを作る<a href="https://gitstar-ranking.com/">Webサイト</a>を作ったりした。</p> <p>このサイトによると、僕の今のスター数は9000を超えている。</p> <center><span itemscope itemtype="http://schema.org/Photograph"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/k/k0kubun/20231102/20231102135132.png" width="200" height="200" loading="lazy" title="" class="hatena-fotolife" itemprop="image"></span></center> <p>自作したOSSの中では、スター数が1600くらいのものが2つ、970くらいものが2つ、700-800くらいのものが3つ、 300くらいのものが2つある。GitHubのアチーブメントでStarstruck x3 (☆512) を達成するプロジェクトは量産しているが、 Starstruck x4 (☆4096) を達成するものは1つもない、という感じになっている。</p> <p>この10年を振り返ってみて、正直これはあんまり上手くなかったと思っている。 というのも、☆512 のリポジトリを10個持つより、 ☆4096 のリポジトリを1つ持つ方が代表作として人々の記憶に残りやすいし、 メンテの効率も良くなるし、世界に与えるインパクトも大きくなる可能性が高いからだ。</p> <p>一方で必ずしも多作が悪いということではなく、<a href="https://github.com/fluent">Fluentd</a>や<a href="https://github.com/msgpack">MessagePack</a>といった Starstruck x4クラスのプロジェクトを何度も世に送り出した <a href="https://twitter.com/frsyuki">@frsyuki</a> さんという完全上位互換みたいな存在もいるので、 そういうパスもあることは書いておきたい。 これどうやってたのかというのが気になりすぎて、<a href="https://magazine.rubyist.net/articles/0061/0061-Hotlinks.html">Rubyist Hotlinks</a>という連載では僕の回の次に古橋さんを指名して、 インタビューは収録済みで公開待ちというステータスなのだけど、とても良い話が聞けたので乞うご期待。</p> <h1 id="なぜ戦うのか">なぜ戦うのか</h1> <p>楽しいからだ。 OSSに限らず一般に、以下のような条件を満たす問題解決に取り組むのは楽しい。 <a href="#f-d7bfbc5a" name="fn-d7bfbc5a" title="僕は汎用プログラミング言語の最適化に今最も興味があり、本番環境で満足な性能のものが他になく自分がコミッターである経験が活きてくるCRubyという言語処理系で、YJITというJITコンパイラを開発する仕事に楽しさを感じる、という話。">*1</a></p> <ol> <li>自分が最も興味がある分野で</li> <li>まだ他の人に十分解決されておらず</li> <li>自分の能力や知識が活きやすい問題</li> </ol> <p>そういった問題を解決するソフトウェアを書く時に、興味が一致するかわからない現在の所属企業で予算や人を集めて始めるよりは、 業務外で個人で作り始める方がよっぽど実現ハードルが低いので、そういう意味で個人開発はありがちな選択肢になる。</p> <p>僕の場合はコードを秘密にして他者を出し抜きたいみたいな気持ちがなく、 むしろお互いのコードをオープンにして議論を深める環境に身を置く方が知的好奇心が満たされるため、 個人で書いたソフトウェアは基本的にオープンソースにしている。</p> <p>より多くの人に使ってもらった方がより難しい問題に挑戦する機会が増えるし、当然承認欲求も満たされるので、 せっかくなら可能な限りバズらせてスターを集めて楽しくやりたいと思っている。 あと、純粋に数字を伸ばすことにこだわっていたとしても、 持続性や自分のパフォーマンスの維持のため、どっちにしても楽しさの追求は重要になると思われる。</p> <h1 id="OSSとインフルエンサー">OSSとインフルエンサー</h1> <p>yusukebe さんの記事にこういう話があった。</p> <blockquote><p>声を上げることは昨今のOSSでは強力な戦闘力になる。 我々は、なかなかこの文脈に我々は入れない。 それは英語ができないからではない。日本語で話している環境の中で英語で発信しても力にならないからだと思う。</p></blockquote> <p>大筋同意なのだけど、「日本語で話している環境の中で英語で発信しても力になる」ケースは普通にあると思っている。この戦闘力は本質的には「目的の環境でインフルエンサーに気にかけてもらえる力」<a href="#f-0670e8a2" name="fn-0670e8a2" title="自分自身がインフルエンサーになれている場合も当然含まれる">*2</a> であると僕は捉えていて、英語を喋っている人の方がよくリーチするのでインフルエンサーになりやすく、そこに一方的に英語で発信するだけでは不十分で、何らかの方法でその人たちの気を引く必要があるがこれが難しい、という構造だと思っている。</p> <p>やり方はいろいろあるが、海外のカンファレンスに何度も参加して仲の良い関係になるとか、そういう人たちが多く所属する会社やチームに入ってしまうとか、影響力のあるポッドキャストに出るなどして知ってもらうとか、そういう比較的難易度の高い話。<a href="#f-83a836fc" name="fn-83a836fc" title="なんか当人達に読まれると恥ずかしい気がするので具体名は出してないのだが、この3つの例は全て実践しているつもり。">*3</a> 一度そういうコネができると、日本のコミュニティに囲まれている場所で(英語で)発信していても、 英語圏のインフルエンサーの会話の輪に入れてもらったり、自然と自分の発信を取り上げてもらえたりする。 その先は発信するネタの質の問題だと思われる。</p> <h1 id="英語のXアカウント">英語のXアカウント</h1> <p>どちらにしても、英語で発信するのであれば投稿する内容は英語オンリーにした方がフォロワー獲得の効率は当然良くなると思われる。 僕の場合は自分の英語の練習および英語話者のコミュニティや元/現同僚とのコミュニケーションのためにXの投稿をリプライ以外は英語に倒しているのだが、 それでもフォロー/フォロワーの日本人比率は依然として高く、正直まだ日本語圏で活動してるなという感覚が強い。</p> <p>僕のように英語アカウントにコンバートするデメリットは、 日本語圏で(ブログではなく普通の)ポストをバズらせたりフォロワーを獲得したりみたいなのが明らかに難しくなっている点で、 英語発信用アカウントを例えば <a href="https://twitter.com/honojs">@honojs</a> のような形で分離するのに成功した場合はどちらのコミュニティにも効率良く発信できそうでいいなという感じがする。とはいえ、僕の日本語の細かな発信に関しては、日本語のSlackやZulip <a href="#f-b31da7b8" name="fn-b31da7b8" title="オープンな奴だと ruby-jp, vim-jp, rust-lang-jp, prog-lang-sys-ja">*4</a> で割とベラベラ話してるので、まあそれでいいかという気もする。</p> <p>子ネタとして極端な例を出しておくと、Matzは日本語の投稿が多いけど明らかに英語圏の多くの人が(おそらく翻訳機能を使って)読んでいるし、 Railsコミッター四皇の <a href="https://twitter.com/kamipo">@kamipo</a> さんはアイドルや食べ物などに関する日本語の投稿が多いけど、 英語圏でかなり影響力があると思われるDHHにフォローされている。 僕にも彼らのようなパワーがあればもっと自由に発信できたのに、と思う。</p> <h1 id="英語圏へのリーチ">英語圏へのリーチ</h1> <p>yusukebe さんの記事では名前が登場しなかったが、Redditは比較的敷居が低く、かつターゲット層にリーチさせやすいので便利だと思う。 ある種英語圏のはてなブックマークのような存在だけど、人気投稿に加えて新規投稿もそこそこ露出する仕組みになってるので、 アカウントを作って突然GitHubリポジトリのリンクを張るだけでも割とスター伸ばしに貢献するような印象がある。 何かスターが伸びてるなと思ったら、誰かが自分のプロジェクトをRedditで褒めてくれていた、みたいなこともあった。</p> <p>まあでもやっぱり本命はHacker Newsかなと思う。 Redditだと良くも悪くもプログラミング言語などでコミュニティが分断されたSubredditを使いがちだが、 Hacker Newsだと全テックコミュニティが混ざるので人の目が多くなるし、 こちらのトップに載る方がインパクトが大きい印象を受ける。 業務時間中にRuby関係のスレに同僚がよくコメントしまくっている様子を見るのだが、 それくらい皆気にかけているということ。</p> <p>僕が書いたもののうち2つが今年Hacker Newsのトップページに載ることに成功した。</p> <ul> <li><a href="https://news.ycombinator.com/item?id=35054163">RJIT, a new JIT for Ruby</a> (336 points, <a href="https://hnrankings.info/35054163/">2位</a>)</li> <li><a href="https://news.ycombinator.com/item?id=37579926">Ruby 3.3's YJIT Runs Shopify's Production Code 15% Faster</a> (175 points, <a href="https://hnrankings.info/37579926/">2位</a>)</li> </ul> <p>どちらも僕自身でHacker Newsに掲載したものではないが、 X上で(上述したような方法でできたRuby界のコネにより)インフルエンサーによってシェアやリポストされた結果、 日本人がはてブでコメントを書くようなモチベーションで、 Hacker News上でコメントしたい人がでてきて伸びたという感じだと思われる。</p> <h1 id="神対応">神対応</h1> <p>issueで機能要望が上がってきた時、即日実装してクローズするみたいな生活を繰り返していると、 それだけでGitHub Sponsorになったよ、という人が出てくる程度にはそういった「神対応」にはOSSを伸ばす力がある。</p> <p>それはそうなんだけど、「神」という名前がふさわしい程度に希少であるのには理由があって、 例えば複数プロジェクトでアクティブに要望が来続けると、割と簡単に1人の人間のキャパシティを超える。 僕はフルタイムで仕事を続けながら0歳児が生まれてからの<a href="https://k0kubun.hatenablog.com/entry/graduation">1年9か月でCS修士を取る</a>という無茶をしていたことがあるが、3歳児となった今の方が子の睡眠のスケジュールが不安定で作業時間の確保が難しくなっており、 その上で家の事務処理やプリスクールとかで発生する雑務も全てこの作業時間に押し込む結果、 業務以外でOSSをやるのはissueを書いてきた人自身にパッチを書いてもらってマージするのが精一杯という感じになっている <a href="#f-4c12a8b5" name="fn-4c12a8b5" title="ところで直近少し返事も滞ってるのがあるんだけど、これは出張の後に風邪を引くというコンボが発生したため。この記事を書きたい気持ちが強すぎて今はこれを書いてるけど、明日は(風邪の症状がマシになっていれば)そのあたりに対応する。">*5</a>。</p> <p>「神対応」が可能になるのは早くても子が小学校に入ってからかな、という感じだが、 まあそもそも子供と時間を過ごす方が他人のOSSのissueを実装するより楽しいし、 一番興味があるOSSは業務時間中に触れるので、現状に何か不満があるわけではない。</p> <h1 id="コントリビューター">コントリビューター</h1> <p>神対応不可能性に対する解としては、それをフルタイムのジョブにしてしまうというのが多分最も持続性がある。 僕は自分が一番興味があるRubyのYJIT開発にそれを充て、 業務外のプロジェクトの開発スピードはある程度諦めることによって(OSS)ワークライフバランスを保っている。</p> <p>とはいえ、自分の仕事にならなかったとしても、使う人がいるものに関しては可能な限り速く開発された方がいいので、 業務外のOSSはなるべくissueを出した人に自分で実装する手助けをしたり、 力がある人にはメンテナになってもらうなどすることで、可能な限り最大のスループットを出そうとしている。 <a href="https://github.com/k0kubun/sqldef">sqldef</a>はありがたいことにそこそこメンテナがいるけど、 <a href="https://github.com/k0kubun/sqldef">sqldef</a>と<a href="https://github.com/k0kubun/xremap">xremap</a>あたりは引き続きメンテナを増やしていきたい感じなので、興味がある人は声をかけて欲しい。</p> <h1 id="英語">英語</h1> <p>東京にいたころ、隣の机にいる上司が英語ネイティブでかつ彼と比較的高頻度で話す必要があった時期があるのだが、 その1年が僕の英会話力は一番伸びた感じがあり、そこで業務に必要なラインも超えた気がする。 そういう環境にどうにか自分を突っ込むというのが一番効率がいい。</p> <p>プログラミングに関わる語彙が基本的に英語と日本語で共通してる関係上、 業務に必要な会話で語彙に困ることはほぼない。 これは裏を返すと、要求語彙力的には「業務に必要なライン」は「日常会話に必要なライン」 を遥かに下回ることを意味しており、正直仕事以外の雑談は未だに理解に失敗することが多い。 それでも「OSSで世界と戦う」という要件では困ることはない。</p> <h1 id="時差">時差</h1> <p>北米東海外がメインのタイムゾーンの会社にいるんだけど、 このタイムゾーンは日本とはほぼ真逆なので日本の人がMTGを持つことは実質不可能で、 チームメンバーの構成次第では一人だけ日本にいられても困るみたいなことは普通に有り得る。</p> <p>まあ…普通に移住するのが良い。 短期的には円安という話もあるが、そうでなくても東京とニューヨーク/サンフランシスコの間には凄まじい給与格差がどの企業でも存在しているため、 移住するだけで少なくとも金銭的には得をする可能性が高い。</p> <h1 id="OSSで戦うために">OSSで戦うために</h1> <p>僕の中で一貫しているのは「楽しくやる」という点かなと思う。OSSで数字を伸ばしたりお金を稼いだりすることよりも、自分が取り組んでいることを真に楽しめていて、プライベートも楽しく暮らせるみたいなことの方が大事だと思っている。</p> <div class="footnote"> <p class="footnote"><a href="#fn-d7bfbc5a" name="f-d7bfbc5a" class="footnote-number">*1</a><span class="footnote-delimiter">:</span><span class="footnote-text">僕は汎用プログラミング言語の最適化に今最も興味があり、本番環境で満足な性能のものが他になく自分がコミッターである経験が活きてくるCRubyという言語処理系で、YJITというJITコンパイラを開発する仕事に楽しさを感じる、という話。</span></p> <p class="footnote"><a href="#fn-0670e8a2" name="f-0670e8a2" class="footnote-number">*2</a><span class="footnote-delimiter">:</span><span class="footnote-text">自分自身がインフルエンサーになれている場合も当然含まれる</span></p> <p class="footnote"><a href="#fn-83a836fc" name="f-83a836fc" class="footnote-number">*3</a><span class="footnote-delimiter">:</span><span class="footnote-text">なんか当人達に読まれると恥ずかしい気がするので具体名は出してないのだが、この3つの例は全て実践しているつもり。</span></p> <p class="footnote"><a href="#fn-b31da7b8" name="f-b31da7b8" class="footnote-number">*4</a><span class="footnote-delimiter">:</span><span class="footnote-text">オープンな奴だと ruby-jp, vim-jp, rust-lang-jp, prog-lang-sys-ja</span></p> <p class="footnote"><a href="#fn-4c12a8b5" name="f-4c12a8b5" class="footnote-number">*5</a><span class="footnote-delimiter">:</span><span class="footnote-text">ところで直近少し返事も滞ってるのがあるんだけど、これは出張の後に風邪を引くというコンボが発生したため。この記事を書きたい気持ちが強すぎて今はこれを書いてるけど、明日は(風邪の症状がマシになっていれば)そのあたりに対応する。</span></p> </div> k0kubun 自作PC2023: Ryzenをやめた hatenablog://entry/6801883189052049625 2023-10-20T18:28:29+09:00 2023-10-21T05:18:21+09:00 Ryzenはゲーム用CPUとしては特に問題ないのだが、 ソフトウェア開発においてはIntelのCPUに比べて不便なポイントがいくつかある。 日々業務で使っていてあまりにもストレスが溜まるので、CPUをIntel Core i7に変更した。 このマシンは8年前に組んだ自作PC なのだが、使っていて不便を感じたパーツを差し替え続けた結果、 今回のアップデートで全てのパーツが当時とは違うものに変わったため、 それぞれ古い方のパーツで不便だったポイントなどを紹介したい。 仕事で使う自作PC 社内のサービスをいじる時は会社から貸与されているM1 MacBook Proを使うのだが、このマシンは不便である… <p>Ryzenはゲーム用CPUとしては特に問題ないのだが、 ソフトウェア開発においてはIntelのCPUに比べて不便なポイントがいくつかある。 日々業務で使っていてあまりにもストレスが溜まるので、CPUをIntel Core i7に変更した。</p> <p>このマシンは<a href="https://k0kubun.hatenablog.com/entry/2015/08/16/162142">8年前に組んだ自作PC</a> なのだが、使っていて不便を感じたパーツを差し替え続けた結果、 今回のアップデートで全てのパーツが当時とは違うものに変わったため、 それぞれ古い方のパーツで不便だったポイントなどを紹介したい。</p> <p><span itemscope itemtype="http://schema.org/Photograph"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/k/k0kubun/20231020/20231020172816.jpg" width="1200" height="901" loading="lazy" title="" class="hatena-fotolife" itemprop="image"></span></p> <h1 id="仕事で使う自作PC">仕事で使う自作PC</h1> <p>社内のサービスをいじる時は会社から貸与されているM1 MacBook Proを使うのだが、このマシンは不便である。 Rubyのビルドは自分のLinuxのマシンに比べ2倍以上遅いし、Reverse Debuggingができるデバッガが存在しないし、 慣れたツールであるLinux perfも使えないし、Podmanを使う会社なのだが当然Linux上でDockerを使う方が便利だし、 命令幅が32bitな関係で主に64bitの値を扱うRubyのJITコードは読みづらい。</p> <p>僕はOSSの開発が主業務なのだが、OSS開発はMacから自作のLinuxマシンにsshしてそこで作業している。 ssh越しにtmuxを立ち上げ、マシン間でクリップボードを同期する仕組みも自作した結果、ローカル環境がLinuxかのような快適さで作業ができている。 会社のお金でLinuxマシンを立ち上げることもできるが、 rr-debuggerや安定したベンチマーク環境が必要な関係でベアメタルなマシンが必要になりがちで、 これは高いので使う時間は最小限にする必要があるが、それが不要な手元のマシンは楽である。</p> <h1 id="使っているパーツ">使っているパーツ</h1> <p>現在使っているパーツの一覧はこちら。</p> <table> <thead> <tr> <th style="text-align:left;"> 種類 </th> <th style="text-align:left;"> 名称 </th> <th style="text-align:left;"> 値段 </th> <th style="text-align:left;"> 購入日 </th> </tr> </thead> <tbody> <tr> <td style="text-align:left;"> CPU </td> <td style="text-align:left;"> Intel Core i7-12700KF </td> <td style="text-align:left;"> $219 </td> <td style="text-align:left;"> 2023/10/13 </td> </tr> <tr> <td style="text-align:left;"> CPUクーラー </td> <td style="text-align:left;"> ID-COOLING ZOOMFLOW 240X ARGB </td> <td style="text-align:left;"> $64 </td> <td style="text-align:left;"> 2023/07/16 </td> </tr> <tr> <td style="text-align:left;"> ケース </td> <td style="text-align:left;"> NZXT H7 Flow </td> <td style="text-align:left;"> $113 </td> <td style="text-align:left;"> 2023/10/15 </td> </tr> <tr> <td style="text-align:left;"> マザーボード </td> <td style="text-align:left;"> ASUS Prime B760-PLUS D4 </td> <td style="text-align:left;"> $120 </td> <td style="text-align:left;"> 2023/10/13 </td> </tr> <tr> <td style="text-align:left;"> メモリ </td> <td style="text-align:left;"> TEAMGROUP Elite DDR4 16GB x 4 </td> <td style="text-align:left;"> $67 x 4 <a href="#f-ce51877a" name="fn-ce51877a" title="バラバラに買っているので、買ったタイミングごとに値段が異なり、$67というのは平均の値段。2021/01/11: $55, 2021/05/29: $77, 2021/07/17: $68 x 2">*1</a> </td> <td style="text-align:left;"> 2021/01/11 </td> </tr> <tr> <td style="text-align:left;"> GPU </td> <td style="text-align:left;"> ZOTAC GeForce RTX 3060 </td> <td style="text-align:left;"> $550 </td> <td style="text-align:left;"> 2021/05/28 </td> </tr> <tr> <td style="text-align:left;"> SSD </td> <td style="text-align:left;"> TEAMGROUP T-FORCE 1TB M.2 </td> <td style="text-align:left;"> $93 </td> <td style="text-align:left;"> 2021/08/12 </td> </tr> <tr> <td style="text-align:left;"> 電源 </td> <td style="text-align:left;"> ROSEWILL 80 Plus Gold 750W </td> <td style="text-align:left;"> $70 </td> <td style="text-align:left;"> 2019/11/29 </td> </tr> </tbody> </table> <p>合計 $1,497 <a href="#f-bd8118e5" name="fn-bd8118e5" title="なお、複数同時に購入した時の商品あたりの税金の計算が面倒だったため、値段は全て税抜である。">*2</a>。 RTX 3060は<a href="https://k0kubun.hatenablog.com/entry/graduation">Deep Learningの授業</a>で必要になって買った、 当時入手可能な中では安かったRTXで、僕の普段の用途だと過去に持ってた $50 の適当なGPUで置き換えても問題ないし、 メモリの半分もその授業のために盛った本来不要なものなので、実質 $863 で僕の開発環境は再現できそう。</p> <p><a href="https://k0kubun.hatenablog.com/entry/2015/08/16/162142">8年前に組んだPC</a>は98,316円で、 当時はこれと家賃と持株会で1か月の給料を使い切ったようだが、 円安の関係で今は年収が当時の12倍になったため、特に無理なく買えるようになった。 生活が苦しくてiMacをヤフオクした時の苦労が嘘のようだ。 円安最高!</p> <h2 id="CPU">CPU</h2> <p><div class="hatena-asin-detail"><a href="https://www.amazon.co.jp/dp/B09FXKHN7M?tag=hatena-22&amp;linkCode=ogi&amp;th=1&amp;psc=1" class="hatena-asin-detail-image-link" target="_blank" rel="noopener"><img src="https://m.media-amazon.com/images/I/41S0TSQIjsL._SL500_.jpg" class="hatena-asin-detail-image" alt="Intel Corei7 プロセッサー 12700KF 3.6GHz( 最大 5.0GHz ) 第12世代 LGA 1700 BX8071512700KF" title="Intel Corei7 プロセッサー 12700KF 3.6GHz( 最大 5.0GHz ) 第12世代 LGA 1700 BX8071512700KF"></a><div class="hatena-asin-detail-info"><p class="hatena-asin-detail-title"><a href="https://www.amazon.co.jp/dp/B09FXKHN7M?tag=hatena-22&amp;linkCode=ogi&amp;th=1&amp;psc=1" target="_blank" rel="noopener">Intel Corei7 プロセッサー 12700KF 3.6GHz( 最大 5.0GHz ) 第12世代 LGA 1700 BX8071512700KF</a></p><ul class="hatena-asin-detail-meta"><li>インテル(Intel)</li></ul><a href="https://www.amazon.co.jp/dp/B09FXKHN7M?tag=hatena-22&amp;linkCode=ogi&amp;th=1&amp;psc=1" class="asin-detail-buy" target="_blank" rel="noopener">Amazon</a></div></div></p> <h3 id="Ryzenをやめた理由">Ryzenをやめた理由</h3> <p>僕の仕事はJITコンパイラの開発なのだが、この業務でよく使うツールがrr-debugger <a href="#f-ee1075e1" name="fn-ee1075e1" title="Reverse Debugging機能がついたGDBのフォーク。GDBにはReverse Debuggingが元々ついているのだが、これはあんまりまともに動かないし、 サブコマンドの利便性的にもReverse DebuggingをするならGDBではなくrr-debugger一択である。 言語処理系のデバッグをする時に、とりあえずクラッシュさせてからリバースステップ実行で原因を調査するみたいなのは大変便利で、 これは必須のツールと言える。M1 MacではそもそもGDBすら動かないし、LLDBにはReverse Debuggingはないので、まあMacは全然使う気にならない。">*3</a> とLinux perfである。 Ryzenでもこれらは使うことが一応可能なのだが、Intel CPUで使う場合に比べると、どちらも少し不便。 rrのために毎日<a href="https://github.com/rr-debugger/rr/wiki/Zen">zen_workaround.py</a>を叩くのだが、 こんな名前のスクリプトを日々叩かされたらRyzenに嫌気が差して当然である。 perfはLBR<a href="#f-cf8a0d64" name="fn-cf8a0d64" title="Last Branch Record。僕が開発しているYJITではperf上でフレームのunwindingが動かなかった (それを可能にする変更を最近マージした) のだが、 LBRはハードウェア側でアドレスの履歴を記録することで動くため、YJIT使用時もスタックトレースが問題なく取れるという利点がある。">*4</a> が動かないし、<a href="https://man7.org/linux/man-pages/man1/perf-list.1.html#EVENT_MODIFIERS">Event Modifier</a>の:upや:pppが動かなかったりする。</p> <p>普通は耐えられるレベルの不便さだと思うが、業務でよく使う二大ツールでストレスを溜め続けるのも嫌だし、 Prime Big Deal Daysでかなり安かった割に性能も結構改善しそうな見込みがあったので、乗り換えを決意した。</p> <h3 id="Ryzen-7-5800X-vs-Core-i7-12700KF">Ryzen 7 5800X vs Core i7-12700KF</h3> <p>そもそもi7-12700KFは第12世代で、最新の第13世代のCPUに比べると少し古い。 2020/11/05に出たRyzen 7 5800Xに比べて、2021/11/04に出たCore i7-12700KFはたった1年分しか新しくなってないのだが、 <a href="https://www.cpubenchmark.net/singleThread.html">PassMark Single Thread</a>を見ると、17%くらい性能が改善していることになっている。</p> <p><a href="https://k0kubun.hatenablog.com/entry/ryzen7-5800x">RyzenでPCを組み直したら爆速で最高になった</a> という記事を書いた時は、趣味で開発していたRuby 3.0 MJITを<a href="https://github.com/mame/optcarrot">NESエミュレータ</a>でベンチマークしたが、 今回も同じベンチマークを使い、今は仕事で開発しているRuby 3.3 YJITで比較してみた。</p> <table> <thead> <tr> <th style="text-align:left;"> Ryzen 7 5800X </th> <th style="text-align:left;"> Core i7-12700KF </th> </tr> </thead> <tbody> <tr> <td style="text-align:left;"> 201.17fps </td> <td style="text-align:left;"> 287.57fps </td> </tr> </tbody> </table> <p>速い! そもそも<a href="https://k0kubun.hatenablog.com/entry/ryzen7-5800x">前回の記事</a>では142.09fpsだったわけなので、 Ruby自体の性能の進歩にも喜びたいところだけど、実装同じで今回のCPUの差し替えだけで43%速くなったのもすごいなと思う。 これは元々Ruby 2だと20fpsで動く想定のベンチマークで、 Ruby 3ではこれを60fpsで動かせたら3倍速くなってRuby 3x3だねというベンチマークなんだけど、 今はRuby 3x14くらいある。</p> <h2 id="CPUクーラー">CPUクーラー</h2> <p><div class="hatena-asin-detail"><a href="https://www.amazon.co.jp/dp/B085PXXQWC?tag=hatena-22&amp;linkCode=ogi&amp;th=1&amp;psc=1" class="hatena-asin-detail-image-link" target="_blank" rel="noopener"><img src="https://m.media-amazon.com/images/I/41R42CAvunL._SL500_.jpg" class="hatena-asin-detail-image" alt="ID-COOLING ZOOMFLOW 240X ARGB CPUウォータークーラー 5V ARGB AIOクーラー 240mm CPU液体クーラー 2X120mm RGBファン Intel 115X/1200/2066 AMD AM4/AM5" title="ID-COOLING ZOOMFLOW 240X ARGB CPUウォータークーラー 5V ARGB AIOクーラー 240mm CPU液体クーラー 2X120mm RGBファン Intel 115X/1200/2066 AMD AM4/AM5"></a><div class="hatena-asin-detail-info"><p class="hatena-asin-detail-title"><a href="https://www.amazon.co.jp/dp/B085PXXQWC?tag=hatena-22&amp;linkCode=ogi&amp;th=1&amp;psc=1" target="_blank" rel="noopener">ID-COOLING ZOOMFLOW 240X ARGB CPUウォータークーラー 5V ARGB AIOクーラー 240mm CPU液体クーラー 2X120mm RGBファン Intel 115X/1200/2066 AMD AM4/AM5</a></p><ul class="hatena-asin-detail-meta"><li>ID-COOLING</li></ul><a href="https://www.amazon.co.jp/dp/B085PXXQWC?tag=hatena-22&amp;linkCode=ogi&amp;th=1&amp;psc=1" class="asin-detail-buy" target="_blank" rel="noopener">Amazon</a></div></div></p> <p>水冷クーラーを使っている。<a href="https://k0kubun.hatenablog.com/entry/ryzen7-5800x">前回の記事</a>では空冷を使っていたのだが、 空冷は良い性能のものはヒートシンクがめちゃくちゃでかく、これがケースの容量をかなり圧迫して取り回しがしづらくなるし、 それで狭くなるのに加えてヒートシンクが鋭利なことで割と手を切ったりする。</p> <p>これを買い換えたのは、ちょっと負荷の高い使い方をしたらPCがクラッシュするようになったのがきっかけで、 CPUクーラーを水冷に換えたら問題が発生しなくなった。 また、水冷は省スペースな上に元々使っていた空冷クーラーより静かだったので、今後は水冷しか使わないと思う。 元々水冷を避けていたのは機器の寿命や液漏れを心配していたからだが、 このクーラーのポンプの想定寿命は6年弱で、正しく扱えば液漏れの確率も低いようだし、NZXT H1 <a href="#f-f3eff4de" name="fn-f3eff4de" title="CPUクーラーじゃないけど、NZXT H1は発火することが原因でリコールされたPCケース">*5</a> みたいに発火するのに比べたらマシな気がする。</p> <h2 id="ケース">ケース</h2> <p><div class="hatena-asin-detail"><a href="https://www.amazon.co.jp/dp/B09VNRGT7S?tag=hatena-22&amp;linkCode=ogi&amp;th=1&amp;psc=1" class="hatena-asin-detail-image-link" target="_blank" rel="noopener"><img src="https://m.media-amazon.com/images/I/51kj5Y5S6bL._SL500_.jpg" class="hatena-asin-detail-image" alt="NZXT H7 Flow ミドルタワーPCケース [White&amp;Black] CM-H71FG-01 CS8453" title="NZXT H7 Flow ミドルタワーPCケース [White&amp;Black] CM-H71FG-01 CS8453"></a><div class="hatena-asin-detail-info"><p class="hatena-asin-detail-title"><a href="https://www.amazon.co.jp/dp/B09VNRGT7S?tag=hatena-22&amp;linkCode=ogi&amp;th=1&amp;psc=1" target="_blank" rel="noopener">NZXT H7 Flow ミドルタワーPCケース [White&amp;Black] CM-H71FG-01 CS8453</a></p><ul class="hatena-asin-detail-meta"><li>NZXT</li></ul><a href="https://www.amazon.co.jp/dp/B09VNRGT7S?tag=hatena-22&amp;linkCode=ogi&amp;th=1&amp;psc=1" class="asin-detail-buy" target="_blank" rel="noopener">Amazon</a></div></div></p> <p>8年間唯一同じものを使い続けた、最も長持ちしたパーツがケースである。 本当はCPUとマザボだけ買い替えるつもりだったのだが、 マザボを取り付けるネジがガバガバになってしまい寿命ぽいなと思ったのでケースも買い替えた。</p> <p><a href="https://r7kamura.com/articles/2021-01-08-pc-build-2021">r7kamuraさん</a>や <a href="https://yoshiori.hatenablog.com/entry/2023/04/19/170439">yoshioriさん</a> が使っているのを見て前々からNZXTが気になっていたので、NZXTのケースにした。 YouTubeとかでレビューを結構眺めたんだけど、NZXT H7 Flowは評判がいい。 NZXT H7については、Eliteは穴が少ない分見た目がかっこいい反面Flowと違って冷却性能が悪く音もうるさいらしいので、 穴だらけのFlowが無難と思われる。</p> <p>最近のケースはマザボ側をガラスにして中身が見えるようにするのが流行っている <a href="#f-94e825c3" name="fn-94e825c3" title="ガラスは割れるらしいので、実用的には普通にマイナスな気もする。 他に不便になった点としては、DVDドライブをつける場所がモダンなケースには基本ないというものがあるが、 まあ必要になったらUSB接続で外付けの奴を使う、で十分な気がする">*6</a> ようで、これもそうなっている。 中身が見える影響か、配線が綺麗にできるような工夫が随所にあって、それがこのケースを買って一番嬉しかったポイント。 ガラスになっている前面がインスタ映えするのは、背面にケーブルを送りまくっているだけというのがオチのようだが、背面もケーブルをまとめるための仕掛けがいい感じになっていて、背面の方も以下のようにそこそこ綺麗 <a href="#f-8dd3bfc7" name="fn-8dd3bfc7" title="とかいいつつ大分スパゲッティな絡み方をしているが、全くリファクタリングをしてない状態がこれなので、改善はできるかもしれない。でも当分パーツ差し替える予定ないしやらないかも…">*7</a>。あとSSDのスロット<a href="#f-9bc8c78e" name="fn-9bc8c78e" title="ところでこれはSSDのところで解説しているM.2 SSDとは別のSSD 2つで、まああんま使ってないけどとりあえずつけてるだけなので、パーツ一覧には含めなかった (追記: なお、これにはWindowsとArch Linuxが入っていて、それぞれの環境のサポートの動作確認用に維持しており、使用頻度は大分低いものの、一応開発目的でつけているものではある。) ">*8</a>も省スペースで良い。</p> <p><span itemscope itemtype="http://schema.org/Photograph"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/k/k0kubun/20231020/20231020171519.jpg" width="1073" height="1200" loading="lazy" title="" class="hatena-fotolife" style="width:300px" itemprop="image"></span></p> <h2 id="マザーボード">マザーボード</h2> <p><div class="hatena-asin-detail"><a href="https://www.amazon.co.jp/dp/B0BR8TRM93?tag=hatena-22&amp;linkCode=ogi&amp;th=1&amp;psc=1" class="hatena-asin-detail-image-link" target="_blank" rel="noopener"><img src="https://m.media-amazon.com/images/I/415rcZS9EML._SL500_.jpg" class="hatena-asin-detail-image" alt="ASUS Prime B760-PLUS D4 Intel(第13世代および第12世代)LGA 1700 ATXマザーボード PCIe 5.0、3xPCIe 4.0 M.2スロット、DDR4、2.5Gb LAN、DisplayPort、USB 3.2 Gen 2x2 Type-C、フロントUSB 3.2 Gen 1 Type-C、Thunderbolt (USB4®)" title="ASUS Prime B760-PLUS D4 Intel(第13世代および第12世代)LGA 1700 ATXマザーボード PCIe 5.0、3xPCIe 4.0 M.2スロット、DDR4、2.5Gb LAN、DisplayPort、USB 3.2 Gen 2x2 Type-C、フロントUSB 3.2 Gen 1 Type-C、Thunderbolt (USB4®)"></a><div class="hatena-asin-detail-info"><p class="hatena-asin-detail-title"><a href="https://www.amazon.co.jp/dp/B0BR8TRM93?tag=hatena-22&amp;linkCode=ogi&amp;th=1&amp;psc=1" target="_blank" rel="noopener">ASUS Prime B760-PLUS D4 Intel(第13世代および第12世代)LGA 1700 ATXマザーボード PCIe 5.0、3xPCIe 4.0 M.2スロット、DDR4、2.5Gb LAN、DisplayPort、USB 3.2 Gen 2x2 Type-C、フロントUSB 3.2 Gen 1 Type-C、Thunderbolt (USB4®)</a></p><ul class="hatena-asin-detail-meta"><li>ASUS</li></ul><a href="https://www.amazon.co.jp/dp/B0BR8TRM93?tag=hatena-22&amp;linkCode=ogi&amp;th=1&amp;psc=1" class="asin-detail-buy" target="_blank" rel="noopener">Amazon</a></div></div></p> <p>前のマザボではUSB-Cに対応してなかったのが気になっていたので、今回はUSB-Cをつけた。 ケースも前にUSB-Cのポートがある奴にした。サイズはいつも通り、大きくて取り回しがしやすいATX。 CPUを買い替える度にソケットの互換性の都合でマザボを買い替えるはめになっているのだが、これはどうにかならんかなと思う。 メモリは前回のマザボからDDR4にしているが、次にマザボ替える時はDDR5になってまたメモリ買い直しとかありそうだし、 CPUクーラーもソケットごとの対応なので互換性なくなるリスクがある。 とりあえず単に要件を満たす一番安い奴を買うようにしている。</p> <h2 id="メモリ">メモリ</h2> <p><div class="hatena-asin-detail"><a href="https://www.amazon.co.jp/dp/B07QRTYYBK?tag=hatena-22&amp;linkCode=ogi&amp;th=1&amp;psc=1" class="hatena-asin-detail-image-link" target="_blank" rel="noopener"><img src="https://m.media-amazon.com/images/I/418oY16AGjL._SL500_.jpg" class="hatena-asin-detail-image" alt="TEAMGROUP Elite DDR4 32GB キット (2 x 16GB) 2666MHz (PC4-21300) CL19 アンバッファード ノンECC 1.2V UDIMM 288ピン PC コンピューター デスクトップ メモリモジュール RAM アップグレード - TED432G2666C19DC01" title="TEAMGROUP Elite DDR4 32GB キット (2 x 16GB) 2666MHz (PC4-21300) CL19 アンバッファード ノンECC 1.2V UDIMM 288ピン PC コンピューター デスクトップ メモリモジュール RAM アップグレード - TED432G2666C19DC01"></a><div class="hatena-asin-detail-info"><p class="hatena-asin-detail-title"><a href="https://www.amazon.co.jp/dp/B07QRTYYBK?tag=hatena-22&amp;linkCode=ogi&amp;th=1&amp;psc=1" target="_blank" rel="noopener">TEAMGROUP Elite DDR4 32GB キット (2 x 16GB) 2666MHz (PC4-21300) CL19 アンバッファード ノンECC 1.2V UDIMM 288ピン PC コンピューター デスクトップ メモリモジュール RAM アップグレード - TED432G2666C19DC01</a></p><ul class="hatena-asin-detail-meta"><li>TEAMGROUP</li></ul><a href="https://www.amazon.co.jp/dp/B07QRTYYBK?tag=hatena-22&amp;linkCode=ogi&amp;th=1&amp;psc=1" class="asin-detail-buy" target="_blank" rel="noopener">Amazon</a></div></div></p> <p>最初16GBで使い始めた。それで十分な気がするが、まあ最近は32GBが人権みたいな風潮があり、何かの拍子に32GBまで増やした。 Deep Learningの授業の時、PyTorchを使っている既存プロジェクトの中に、前処理でやたらメモリを使う奴があって、 それが64GBないと足りないという感じだったので、そこで買い足した。</p> <p>容量はやたら大きいが、それ以外の性能のところは値段のためにあえて妥協したスペックのものを選んでいる。 まだDDR4だし、2666MHzだし、ECCでもない。 ところで、IntelのCPUはXeonとかにしない限りはECCをサポートしていないというのが長く続いていたらしいのだが、 12世代と13世代ではi5やi7でも普通にECCをサポートしているらしい。現にi7-12700KFにもついている。</p> <h2 id="GPU">GPU</h2> <p><div class="hatena-asin-detail"><a href="https://www.amazon.co.jp/dp/B09256CTT3?tag=hatena-22&amp;linkCode=ogi&amp;th=1&amp;psc=1" class="hatena-asin-detail-image-link" target="_blank" rel="noopener"><img src="https://m.media-amazon.com/images/I/41McQpJpwsL._SL500_.jpg" class="hatena-asin-detail-image" alt="ZOTAC Gaming GeForce RTX™ 3060 AMP ホワイトエディション 12GB GDDR6 192ビット 15Gbps PCIE 4.0 ゲーミンググラフィックスカード IceStorm 2.0 冷却 アクティブファンコントロール フリーズファンストップ ZT-A30600F-10P" title="ZOTAC Gaming GeForce RTX™ 3060 AMP ホワイトエディション 12GB GDDR6 192ビット 15Gbps PCIE 4.0 ゲーミンググラフィックスカード IceStorm 2.0 冷却 アクティブファンコントロール フリーズファンストップ ZT-A30600F-10P"></a><div class="hatena-asin-detail-info"><p class="hatena-asin-detail-title"><a href="https://www.amazon.co.jp/dp/B09256CTT3?tag=hatena-22&amp;linkCode=ogi&amp;th=1&amp;psc=1" target="_blank" rel="noopener">ZOTAC Gaming GeForce RTX™ 3060 AMP ホワイトエディション 12GB GDDR6 192ビット 15Gbps PCIE 4.0 ゲーミンググラフィックスカード IceStorm 2.0 冷却 アクティブファンコントロール フリーズファンストップ ZT-A30600F-10P</a></p><ul class="hatena-asin-detail-meta"><li>ZOTAC Gaming</li></ul><a href="https://www.amazon.co.jp/dp/B09256CTT3?tag=hatena-22&amp;linkCode=ogi&amp;th=1&amp;psc=1" class="asin-detail-buy" target="_blank" rel="noopener">Amazon</a></div></div></p> <p>GPU <a href="#f-e70dd599" name="fn-e70dd599" title="買っているもの自体はグラフィックボードとかビデオカードとか言うのが正しいのだが、 性能的にGPU以外の部分はどうでも良いことが多いのでGPUとカテゴライズしている。">*9</a> はRTX 3060なのだが、このシリーズが出た直後に買っていて、当時半導体がめちゃくちゃ不足していたので在庫の確保が大変だったし、 値段もめちゃくちゃ高かった。記憶が正しければ、古いシリーズの中古のRTXの方が最新シリーズの新品を買うより高い状態だった。 従って、新品入荷情報にめちゃくちゃアンテナを張ってどうにか新品を掴むというのが、一番安く買う方法だった。 もう少し安い奴もあったが、在庫を確保するのが難しすぎるのと、ある程度急ぎだったのでこれになった。</p> <p>GPUの性能だけでいうとNVIDIAよりAMDの方がコスパがいいらしいのだが、 Deep Learningという用途の都合CUDAを使いたかったため、実質NVIDIA縛りだった。 NVIDIAのGPUはWaylandの対応も微妙なのだが、僕はアンチWaylandなので関係ない。</p> <p>ゲームも普通に動く性能だし、これは当分買い替えの必要がなさそう。 グラボを持ってると、CPUのオンボードグラフィックが不要になるので、CPUは少し安く買える。</p> <h2 id="SSD">SSD</h2> <p><div class="hatena-asin-detail"><a href="https://www.amazon.co.jp/dp/B08TMQCBWC?tag=hatena-22&amp;linkCode=ogi&amp;th=1&amp;psc=1" class="hatena-asin-detail-image-link" target="_blank" rel="noopener"><img src="https://m.media-amazon.com/images/I/41XlCsY0o0L._SL500_.jpg" class="hatena-asin-detail-image" alt="TEAMGROUP T-Force CARDEA Zero Z330 1TB con lámina de cobre de grafeno 3D NAND TLC NVMe PCIe Gen3 x4 M.2 2280 SSD interna para juegos (lectura/escritura 2.100/1.700 MB/s) para portátil y escritorio TM8FP8001T0C311" title="TEAMGROUP T-Force CARDEA Zero Z330 1TB con lámina de cobre de grafeno 3D NAND TLC NVMe PCIe Gen3 x4 M.2 2280 SSD interna para juegos (lectura/escritura 2.100/1.700 MB/s) para portátil y escritorio TM8FP8001T0C311"></a><div class="hatena-asin-detail-info"><p class="hatena-asin-detail-title"><a href="https://www.amazon.co.jp/dp/B08TMQCBWC?tag=hatena-22&amp;linkCode=ogi&amp;th=1&amp;psc=1" target="_blank" rel="noopener">TEAMGROUP T-Force CARDEA Zero Z330 1TB con lámina de cobre de grafeno 3D NAND TLC NVMe PCIe Gen3 x4 M.2 2280 SSD interna para juegos (lectura/escritura 2.100/1.700 MB/s) para portátil y escritorio TM8FP8001T0C311</a></p><ul class="hatena-asin-detail-meta"><li>Sundeer</li></ul><a href="https://www.amazon.co.jp/dp/B08TMQCBWC?tag=hatena-22&amp;linkCode=ogi&amp;th=1&amp;psc=1" class="asin-detail-buy" target="_blank" rel="noopener">Amazon</a></div></div></p> <p>今どきはSSDといったらM.2一択と思われる。 このパーツもDeep Learningの授業の時、モデルの保管に1TBという大容量が役に立った。 まあそうじゃなくても、128GBのディスクは結構普通に足りなくなる印象で、最低256GBは欲しいし、 Dockerとかをそこそこ使うような開発用途には512GBくらいがちょうどいいのではと思う。</p> <h2 id="電源">電源</h2> <ul> <li><a href="https://www.amazon.com/gp/product/B00NZCBS6A/">ROSEWILL Gaming 80 Plus Gold 750W Power Supply</a> <a href="#f-7bac2168" name="fn-7bac2168" title="はてなブログのAmazon商品埋め込み機能を使っているのだが、このパーツだけは日本のAmazonだとヒットしなかった。そのためリンクだけになっている。">*10</a></li> </ul> <p>電源の品質の等級にいろいろあって、80 Plus Goldはまあそこそこいい奴くらいのつもりで買った気がするが、 これが購入日が一番古い奴なので正直よく覚えていない。 買い替えたのは、マシンが起動しなくなってしまった時で、まあ寿命だったのだと思うが、 起動しない理由は完全にエスパーだった中、期待した通りちゃんと直ってよかった。</p> <p>750Wは割と多めに盛ったつもりだったので、他を買い替える時もいちいち容量を再計算してなかったのだが、 <a href="https://www.newegg.com/tools/power-supply-calculator/">Power Supply Calculator</a> で今見積ってみたら僕の構成は600-699Wだった。十分ぽいけど、めちゃ余裕があるわけでもなさそう。</p> <h1 id="感想">感想</h1> <p><a href="https://k0kubun.hatenablog.com/entry/2015/08/16/162142">8年前の記事</a>を見ると、 およそまともなエンジニアとは思えないめちゃくちゃなことを言っている。</p> <blockquote><p>刺さりそうなピンに勘で適当にケーブルを挿していき、動作するまでの回数を競うゲーム。 一発では動かなくて、よくわからんけど似たようなとこに適当に付け替えたら動いた。やはりエンジニアに必要なのは運命力。</p></blockquote> <p>そんなことはない。 仕組みを理解し、マニュアルの読む必要があるところだけ丁寧に読み、 その通りに配線していくことで、今回は効率良く一発で起動にこぎつけた。</p> <p>PCの組み立てはそれ自体がパズルのようで楽しいが、このようにスキルの上達が感じられるところも面白いポイントだと思う。</p> <div class="footnote"> <p class="footnote"><a href="#fn-ce51877a" name="f-ce51877a" class="footnote-number">*1</a><span class="footnote-delimiter">:</span><span class="footnote-text">バラバラに買っているので、買ったタイミングごとに値段が異なり、$67というのは平均の値段。2021/01/11: $55, 2021/05/29: $77, 2021/07/17: $68 x 2</span></p> <p class="footnote"><a href="#fn-bd8118e5" name="f-bd8118e5" class="footnote-number">*2</a><span class="footnote-delimiter">:</span><span class="footnote-text">なお、複数同時に購入した時の商品あたりの税金の計算が面倒だったため、値段は全て税抜である。</span></p> <p class="footnote"><a href="#fn-ee1075e1" name="f-ee1075e1" class="footnote-number">*3</a><span class="footnote-delimiter">:</span><span class="footnote-text">Reverse Debugging機能がついたGDBのフォーク。GDBにはReverse Debuggingが元々ついているのだが、これはあんまりまともに動かないし、 サブコマンドの利便性的にもReverse DebuggingをするならGDBではなくrr-debugger一択である。 言語処理系のデバッグをする時に、とりあえずクラッシュさせてからリバースステップ実行で原因を調査するみたいなのは大変便利で、 これは必須のツールと言える。M1 MacではそもそもGDBすら動かないし、LLDBにはReverse Debuggingはないので、まあMacは全然使う気にならない。</span></p> <p class="footnote"><a href="#fn-cf8a0d64" name="f-cf8a0d64" class="footnote-number">*4</a><span class="footnote-delimiter">:</span><span class="footnote-text">Last Branch Record。僕が開発しているYJITではperf上でフレームのunwindingが動かなかった (それを可能にする変更を最近マージした) のだが、 LBRはハードウェア側でアドレスの履歴を記録することで動くため、YJIT使用時もスタックトレースが問題なく取れるという利点がある。</span></p> <p class="footnote"><a href="#fn-f3eff4de" name="f-f3eff4de" class="footnote-number">*5</a><span class="footnote-delimiter">:</span><span class="footnote-text">CPUクーラーじゃないけど、NZXT H1は発火することが原因でリコールされたPCケース</span></p> <p class="footnote"><a href="#fn-94e825c3" name="f-94e825c3" class="footnote-number">*6</a><span class="footnote-delimiter">:</span><span class="footnote-text">ガラスは割れるらしいので、実用的には普通にマイナスな気もする。 他に不便になった点としては、DVDドライブをつける場所がモダンなケースには基本ないというものがあるが、 まあ必要になったらUSB接続で外付けの奴を使う、で十分な気がする</span></p> <p class="footnote"><a href="#fn-8dd3bfc7" name="f-8dd3bfc7" class="footnote-number">*7</a><span class="footnote-delimiter">:</span><span class="footnote-text">とかいいつつ大分スパゲッティな絡み方をしているが、全くリファクタリングをしてない状態がこれなので、改善はできるかもしれない。でも当分パーツ差し替える予定ないしやらないかも…</span></p> <p class="footnote"><a href="#fn-9bc8c78e" name="f-9bc8c78e" class="footnote-number">*8</a><span class="footnote-delimiter">:</span><span class="footnote-text">ところでこれはSSDのところで解説しているM.2 SSDとは別のSSD 2つで、まああんま使ってないけどとりあえずつけてるだけなので、パーツ一覧には含めなかった (追記: なお、これにはWindowsとArch Linuxが入っていて、それぞれの環境のサポートの動作確認用に維持しており、使用頻度は大分低いものの、一応開発目的でつけているものではある。) </span></p> <p class="footnote"><a href="#fn-e70dd599" name="f-e70dd599" class="footnote-number">*9</a><span class="footnote-delimiter">:</span><span class="footnote-text">買っているもの自体はグラフィックボードとかビデオカードとか言うのが正しいのだが、 性能的にGPU以外の部分はどうでも良いことが多いのでGPUとカテゴライズしている。</span></p> <p class="footnote"><a href="#fn-7bac2168" name="f-7bac2168" class="footnote-number">*10</a><span class="footnote-delimiter">:</span><span class="footnote-text">はてなブログのAmazon商品埋め込み機能を使っているのだが、このパーツだけは日本のAmazonだとヒットしなかった。そのためリンクだけになっている。</span></p> </div> k0kubun YJITの性能を最大限引き出す方法 hatenablog://entry/820878482954516137 2023-08-01T16:39:57+09:00 2023-12-27T13:38:51+09:00 RubyのJITコンパイラYJITを開発している弊社Shopifyでは、社内で最もトラフィックが多いストアフロントのアプリにRuby 3.3 (master) をデプロイして平均レスポンスタイムが16%高速化、社内で最も大きなアプリであるモノリスにRuby 3.2をデプロイして平均レスポンスタイムが9%高速化している。他の会社でも、YJITを本番で有効にしたら高速化したという事例をちらほら目にした。 一方で必ずしも良い報告ばかりではなく、YJITを有効化したらメモリを使い切ってしまったりだとか、遅くなったみたいな報告も目に入ることがある。こういった問題は我々も多かれ少なかれ経験しており、それぞ… <p>RubyのJITコンパイラYJITを開発している弊社Shopifyでは、社内で最もトラフィックが多いストアフロントのアプリにRuby 3.3 (master) をデプロイして平均レスポンスタイムが16%高速化、社内で最も大きなアプリであるモノリスにRuby 3.2をデプロイして平均レスポンスタイムが9%高速化している。他の会社でも、YJITを本番で有効にしたら高速化したという事例をちらほら目にした。</p> <p>一方で必ずしも良い報告ばかりではなく、YJITを有効化したらメモリを使い切ってしまったりだとか、遅くなったみたいな報告も目に入ることがある。こういった問題は我々も多かれ少なかれ経験しており、それぞれ適切に対処することで解決できたため、その知見を共有する。<a href="#f-b6e19b22" id="fn-b6e19b22" name="fn-b6e19b22" title="余談だが、こういった話のプロポーザルをRubyKaigi 2023に出していたのだが、RJITの方の話が勝ったため話しそびれていた。">*1</a></p> <h1 id="メモリを使い切ってしまった時">メモリを使い切ってしまった時</h1> <p><iframe src="https://hatenablog-parts.com/embed?url=https%3A%2F%2Fzenn.dev%2Fwwwave%2Farticles%2F5f9ef0ddcf8758" title="【未解決】Ruby3.2.0にupdateしてYJITを有効化したら失敗した話" class="embed-card embed-webcard" scrolling="no" frameborder="0" style="display: block; width: 100%; height: 155px; max-width: 500px; margin: 10px 0px;" loading="lazy"></iframe><cite class="hatena-citation"><a href="https://zenn.dev/wwwave/articles/5f9ef0ddcf8758">zenn.dev</a></cite></p> <p>YJITを有効化すると、YJITが生成する機械語に加えて、それに関するメタデータもメモリを消費する。機械語の最大サイズは <code>--yjit-exec-mem-size</code> (デフォルト 64MiB) で制限されるが、メタデータは特にリミットがない。ただし、メタデータサイズは生成コードのサイズに比例する傾向にあり、かつRuby 3.2の時点ではメタデータは生成コードの3~4倍程度メモリを使うと見積っておくと良い<a href="#f-1a8704e6" id="fn-1a8704e6" name="fn-1a8704e6" title="なお、Ruby 3.3ではメタデータのサイズがより小さくなっており、生成コードの2~3倍程度になる。">*2</a>。従って、デフォルトではメモリは最大で256~320MiB使われることになる<a href="#f-a4f6d356" id="fn-a4f6d356" name="fn-a4f6d356" title="メモリは仮想ページごとに必要に応じて割り当てが行なわれるため、アプリのサイズ次第ではメモリ消費量はもっと小さくなる。">*3</a>。</p> <p>ここで注意しなければならないのは、この値はあくまで各プロセスあたりのメモリ消費量であること。UnicornやPumaで複数プロセスを走らせる場合、ワーカーがforkする時点で存在しているメモリのページのうち、その後更新がされないものは複数プロセス間で共有される<a href="#f-03b5c77d" id="fn-03b5c77d" name="fn-03b5c77d" title="Copy on Writeの話をしている">*4</a>が、YJITのコードやメタデータに関しては基本的にワーカーのfork後に生成されるため、メモリの共有は期待できない。そのため、例えばUnicornのプロセスが16ある場合は、最悪の場合 16 x 256~320MiB = 4096~5120MiB 使うことを覚悟しなければならない。</p> <h2 id="--yjit-call-threshold-を大きくする">--yjit-call-threshold を大きくする</h2> <p>一番簡単に試せるのはこれ。デフォルトでは --yjit-call-threshold は30で、つまり30回呼ばれたメソッドからコンパイルを開始するようになっているのだが、アプリの初期化のロジック次第では、この閾値では初期化時にしか使われないコードがコンパイルされてしまうということが有り得る。それらのメモリ消費は後で無駄になるので、この値を大きくするとメモリ使用量が大幅に改善することもある。</p> <p>Shopifyのストアフロントではこれを30よりどれだけ大きくしてもそれほどメモリ使用量は変わらなかったが、20から30に上げた時はメモリ使用量が大幅に減った。あなたのアプリでは30よりもう少し大きくしないとその変化は訪れないかもしれない。なお、これを大きくすればするほどウォームアップが遅くなってしまうため、各ワーカープロセスが処理したリクエスト数合計などのメトリクスと見比べながら、程々の大きさに留める必要がある。</p> <h2 id="--yjit-exec-mem-size-を小さくする">--yjit-exec-mem-size を小さくする</h2> <p>Ruby 3.2のYJITにはCode GCという機構が入った<a href="#f-23736405" id="fn-23736405" name="fn-23736405" title="僕が書いた">*5</a>。これは生成した機械語のサイズが --yjit-exec-mem-size に達したら全てのコードを開放し、その後必要になったコードだけコンパイルして省サイズ化を目指すものだが、ついでにメタデータの方も開放されるため、これを小さくすればするほどメモリ消費量は抑えられることになる。</p> <p>これを小さくしすぎるとCode GCが頻繁に行なわれるようになってしまうため、Code GCがどれくらい頻繁に行なわれているかモニタリングする必要がある。 <code>RubyVM::YJIT.runtime_stats[:code_gc_count]</code> の現在の値をRackミドルウェアなどで定期的に記録しておくと良い。Datadogとかだと <a href="https://github.com/DataDog/dd-trace-rb/pull/2711">DataDog/dd-trace-rb#2711</a> が使えるかもしれない。目安としては、これが0の場合は多少サイズを小さくする余地があり、1で安定する場合や1時間おきに1回走る程度が理想、それより頻繁に値が増える場合はサイズを大きくした方が良い。</p> <h2 id="肥大化したプロセスをkillする">肥大化したプロセスをkillする</h2> <p>ワーカー1つあたりに許容するメモリ使用量をあらかじめ決めておき、それを越えたプロセスを止めるようにするという手も有効である。YJITを使っているかに関わらず、本番でメモリリークが発生してしまった時の供えとしても役に立つ。我々は独自の実装を使っているが、OSSのものでは<a href="https://github.com/kzk/unicorn-worker-killer">unicorn-worker-killer</a>や<a href="https://github.com/zombocom/puma_worker_killer">puma_worker_killer</a>など使えばよさそう。一方で、killの頻度が高いと速度的には悪影響であるため、killの回数もモニタリングしておくのが望ましい。</p> <h2 id="ワーカーをreforkする-上級者向け">ワーカーをreforkする (上級者向け)</h2> <p>同僚の<a href="https://github.com/byroot">@byroot</a>がUnicornのフォークである<a href="https://github.com/shopify/pitchfork">Pitchfork</a>というのを開発した。これはUnicornと比べてレガシーな依存が一つ外れているモダンなUnicornとしても使うことができるが、それに加えて "Reforking" と呼ばれている機能が追加されている。通常、UnicornやPumaのfork時にはアプリのコードがコンパイル済みでないワーカープロセスが作られるが、Reforkingというのはアプリのコードが既にコンパイルされているプロセスを後から定期的にforkし直すことでそのメモリを複数プロセス間で共有することを目指すというもの。YJITの運用でメモリの使用量を最適化しようとしたら、これが一番効果があると思われる。</p> <p>デメリットとしては、スレッドを扱うgemなどがfork-safeでないことがあり、アプリが使っているコードが全てfork-safeであることをどうにか保証しておく必要がある。具体的にはgrpc.gemがこの問題を抱えており、byrootたちがGoogleとコミュニケーションを取ってこれに対応している。それから、PitchforkはUnicornのフォークであるため、Pumaのように各プロセスでマルチスレッドワーカーを立てることはできない。</p> <h2 id="一部ワーカーのみ有効化する-Ruby-33以降">一部ワーカーのみ有効化する (Ruby 3.3以降)</h2> <p>Ruby 3.3では新たに <code>--yjit-disable</code> というフラグと <code>RubyVM::YJIT.enable</code> というメソッドが追加される。この2つを使うと、Ruby起動時にはJITコンパイルを無効にしておき、アプリの初期化が終わった後に手動でコンパイルを開始するということができる。それが主な想定用途なのだが、byrootの発案で、モノリスではUnicorn (Pitchfork) のワーカープロセスのうち、ワーカー番号の若い一部のみ有効化することによって、メモリ使用量を抑えている。これは、Unicornがリクエストを捌く際、全てのワーカーが均等にリクエストを処理するわけではなく、キャパシティに余裕がある場合はワーカー番号が若いものにリクエストが偏るという性質を利用している。そのため、ワークロード次第ではYJITを有効化しているプロセスの割合以上のリクエストがYJIT有効のワーカーに処理されうることになる。</p> <p>Ruby 3.2にはこの機能はないのでRuby 3.3を待っていただく必要があるが、我々は<a href="https://github.com/shopify/ruby-definitions">独自のRuby 3.2フォーク</a>を持っており、これにはこの機能がバックポートされている。</p> <h1 id="遅くなってしまった時">遅くなってしまった時</h1> <p>残念ながら、YJITを本番で有効化したら遅くなったという話もちらほら聞く。</p> <p><blockquote data-conversation="none" class="twitter-tweet" data-lang="en"><p lang="ja" dir="ltr">YJIT 有効化すると遅くなってしまったときに確認する・試すことリストどこかにないですかね🤔🤔</p>&mdash; Pin📍AppBrew CTO (@spinute) <a href="https://twitter.com/spinute/status/1673530026577510401?ref_src=twsrc%5Etfw">June 27, 2023</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script> </p> <p><blockquote data-conversation="none" class="twitter-tweet" data-lang="en"><p lang="ja" dir="ltr">YJITを有効化した結果、レスポンス悪化 <a href="https://twitter.com/hashtag/tqrk14?src=hash&amp;ref_src=twsrc%5Etfw">#tqrk14</a></p>&mdash; hirotea (@nifuchi222222) <a href="https://twitter.com/nifuchi222222/status/1685191647657889792?ref_src=twsrc%5Etfw">July 29, 2023</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script> </p> <h2 id="--yjit-exec-mem-size-を大きくする">--yjit-exec-mem-size を大きくする</h2> <p>YJITを有効化したら遅くなった、と聞いたときに僕が真っ先に疑うのは --yjit-exec-mem-size が小さすぎるというもの。これが小さいとCode GCが頻繁に走りすぎて遅いというリスクが高くなる。その症状になっているかを確認するには、<code>RubyVM::YJIT.runtime_stats[:code_gc_count]</code> をモニタリングし、この値が頻繁に増加していないかを確認すると良い。これが0か1で安定するところまで上げれば、速度的には影響がない状態にできる。</p> <p>弊社ストアフロントでは --yjit-exec-mem-size=64 を使っていて、これは十分すぎるサイズなのだが、一方弊社モノリスでは --yjit-exec-mem-size=256 を使っていて、これを大きくしてきたときに大幅に速度が改善された。これに関連して、Ruby 3.3 (master)ではこのオプションのデフォルトが128に変更されている。</p> <h2 id="ワーカープロセスをなるべく長く走らせる">ワーカープロセスをなるべく長く走らせる</h2> <p>僕が次に疑うのは、ワーカープロセスが定期的にkillされているような環境で、そのkillがあまりにも頻繁すぎるというもの。プロセスが長く走ればコンパイル済みのコードを再利用する機会が増え、速度的には良い影響が期待できる<a href="#f-db0b5387" id="fn-db0b5387" name="fn-db0b5387" title="一方で長く走らせすぎるとメモリが断片化していき若干性能が減衰する問題もあるが、ここで話している問題とは別なので置いておく">*6</a>が、頻繁にkillされるとコンパイルのオーバーヘッドがかかり続けるということが有り得る。各ワーカープロセスが過去に処理したリクエスト数合計などをモニタリングしておき、その値が大きくなる前にプロセスがkillされてしまっている場合は、killの閾値の見直したり、OOMの影響を確認して割り当てるメモリを増やしたりする必要がある。</p> <h2 id="--yjit-call-threshold-を調整する">--yjit-call-threshold を調整する</h2> <p>関連した問題として、--yjit-call-thresholdはワーカーのリクエスト処理数に応じて調整する必要がある。--yjit-call-threshold が小さすぎると、起動時に多くのコードがコンパイルされ、ウォームアップのオーバーヘッドが一気にかかりがちになる。その一方で --yjit-call-threshold を例えば1000まで上げた時、ワーカーが頻繁に再起動されていてプロセスあたり1000リクエスト足らずでkillされてしまっている場合、1000回目のリクエストで初めてコンパイルされるパスが有り得ることになる。その場合は閾値を100くらいまで下げると、より早く、一方で早すぎずウォームアップが行なわれ、速度が改善したりする。</p> <h2 id="ratio_in_yjit-を確認する">ratio_in_yjit を確認する</h2> <p>これはRuby 3.2では少し手間がかかるのだが、Rubyのconfigure時に <code>--enable-yjit=stats</code> をつけてビルドしておき、Rubyの起動時に <code>--yjit-stats</code> をつけ、<code>RubyVM::YJIT.runtime_stats[:ratio_in_yjit]</code> を確認すると、実行されているVM命令のうち何%がYJITで実行されているか確認することができる。ワーカープロセスがピーク性能に達した状態でこれが90%くらいあれば性能が改善していることが期待できるが、これが例えば80%を下回るなどしている場合、アプリのコードかYJITの実装のどちらかに問題があることになる。例えばTracePointがどこかで有効になっていると、ものによってはそれがVM命令を全てtrace命令に書き換えることがあり、その場合YJITはコンパイルを諦めてしまう。いずれにせよ、例えばワーカープロセスが10000リクエスト処理した後もこの値が小さい場合は、<code>--yjit-stats</code> を使用した状態での <code>RubyVM::YJIT.runtime_stats</code> の中身を丸ごとYJITチームに共有<a href="#f-e0a81cc0" id="fn-e0a81cc0" name="fn-e0a81cc0" title="https://bugs.ruby-lang.org/ にチケットを起票するか、https://github.com/Shopify/yjit にissueを書くか、gistとかに貼ってX (Twitter) で僕にリプライなど">*7</a>していただけると、よしなに対応できると思う。</p> <p>Ruby 3.3ではデフォルトのビルドで <code>ratio_in_yjit</code> が確認できるようになっている。YJITが使える全てのRubyのビルドで、起動時に <code>--yjit-stats</code> をつけておけば、<code>RubyVM::YJIT.runtime_stats[:ratio_in_yjit]</code> が利用できる。一方で、Ruby 3.3には <code>ratio_in_yjit</code> を改善する様々な実装が入っており、以前は92%だったのが現在では97%まで改善していたりするので、そもそもこれを確認しなくても速くなるようになっているかもしれない。</p> <h1 id="まとめ">まとめ</h1> <p>簡単にできるアクションのまとめとしては、<code>RubyVM::YJIT.runtime_stats[:code_gc_count]</code> と各ワーカープロセスが処理したリクエスト数をモニタリングし、それらや速度、メモリ使用量に応じて <code>--yjit-call-threshold</code> や <code>--yjit-exec-mem-size</code> を調整したり、割り当てられているメモリのサイズやワーカーのkillの設定などを見直していただくのが良いと思われる。</p> <p>これを読んで「YJITを使うのは面倒くさい」と思った人もいるかもしれないが、これらの知見を可能な限りデフォルトのパラメータにフィードバックしており、基本的にはデフォルトの設定で有効化しただけで特に苦労なく速くなる状態を目指して開発されている。また、より多くのVM命令の対応が日々コミットされ続けているので、Ruby 3.2で遅くても、Ruby 3.3にしたら速くなった、ということも有り得ると思う。</p> <h1 id="参考資料">参考資料</h1> <p>1月に書いた(のを6月にやっと公開した)記事なので若干情報は古いが、会社のブログに書いた以下の記事も参考になるかもしれない。</p> <ul> <li><a href="https://railsatscale.com/2023-06-05-monitoring-yjit-in-production/">Monitoring YJIT in Production</a></li> </ul> <div class="footnote"> <p class="footnote"><a href="#fn-b6e19b22" id="f-b6e19b22" name="f-b6e19b22" class="footnote-number">*1</a><span class="footnote-delimiter">:</span><span class="footnote-text">余談だが、こういった話のプロポーザルをRubyKaigi 2023に出していたのだが、RJITの方の話が勝ったため話しそびれていた。</span></p> <p class="footnote"><a href="#fn-1a8704e6" id="f-1a8704e6" name="f-1a8704e6" class="footnote-number">*2</a><span class="footnote-delimiter">:</span><span class="footnote-text">なお、Ruby 3.3ではメタデータのサイズがより小さくなっており、生成コードの2~3倍程度になる。</span></p> <p class="footnote"><a href="#fn-a4f6d356" id="f-a4f6d356" name="f-a4f6d356" class="footnote-number">*3</a><span class="footnote-delimiter">:</span><span class="footnote-text">メモリは仮想ページごとに必要に応じて割り当てが行なわれるため、アプリのサイズ次第ではメモリ消費量はもっと小さくなる。</span></p> <p class="footnote"><a href="#fn-03b5c77d" id="f-03b5c77d" name="f-03b5c77d" class="footnote-number">*4</a><span class="footnote-delimiter">:</span><span class="footnote-text">Copy on Writeの話をしている</span></p> <p class="footnote"><a href="#fn-23736405" id="f-23736405" name="f-23736405" class="footnote-number">*5</a><span class="footnote-delimiter">:</span><span class="footnote-text">僕が書いた</span></p> <p class="footnote"><a href="#fn-db0b5387" id="f-db0b5387" name="f-db0b5387" class="footnote-number">*6</a><span class="footnote-delimiter">:</span><span class="footnote-text">一方で長く走らせすぎるとメモリが断片化していき若干性能が減衰する問題もあるが、ここで話している問題とは別なので置いておく</span></p> <p class="footnote"><a href="#fn-e0a81cc0" id="f-e0a81cc0" name="f-e0a81cc0" class="footnote-number">*7</a><span class="footnote-delimiter">:</span><span class="footnote-text"><a href="https://bugs.ruby-lang.org/">https://bugs.ruby-lang.org/</a> にチケットを起票するか、<a href="https://github.com/Shopify/yjit">https://github.com/Shopify/yjit</a> にissueを書くか、gistとかに貼ってX (Twitter) で僕にリプライなど</span></p> </div> k0kubun RubyKaigiでJITコンパイラの書き方について発表した hatenablog://entry/820878482933616491 2023-05-18T17:15:46+09:00 2023-05-18T17:34:03+09:00 RubyKaigi 2023でRuby JIT Hacking Guideというタイトルで発表してきた。 speakerdeck.com JITコンパイラを書くチュートリアル 今回の発表ではJITコンパイラが書ける人間を増やすことをゴールにしていたが、 30分という短い発表枠内では雰囲気を知ってもらうことにフォーカスし、 実際に手を動かしたい人たちにはそれ用のチュートリアルを触ってもらう形を取った。 github.com JITコンパイラは実は初心者向き 独学でコンパイラの作り方を学ぶ人は、Cコンパイラなどを実装することが多いように思う。 C言語は実装対象として一見シンプルそうに見えて実は結構… <p>RubyKaigi 2023で<a class="keyword" href="https://d.hatena.ne.jp/keyword/Ruby">Ruby</a> <a class="keyword" href="https://d.hatena.ne.jp/keyword/JIT">JIT</a> Hacking Guideというタイトルで発表してきた。</p> <p><iframe id="talk_frame_1026484" class="speakerdeck-iframe" src="//speakerdeck.com/player/4d30166feb3a4b8f80c83b93b3fc2a62" width="710" height="399" style="aspect-ratio:710/399; border:0; padding:0; margin:0; background:transparent;" frameborder="0" allowtransparency="true" allowfullscreen="allowfullscreen"></iframe> <cite class="hatena-citation"><a href="https://speakerdeck.com/k0kubun/rubykaigi-2023">speakerdeck.com</a></cite></p> <h2 id="JITコンパイラを書くチュートリアル"><a class="keyword" href="https://d.hatena.ne.jp/keyword/JIT">JIT</a><a class="keyword" href="https://d.hatena.ne.jp/keyword/%A5%B3%A5%F3%A5%D1%A5%A4%A5%E9">コンパイラ</a>を書く<a class="keyword" href="https://d.hatena.ne.jp/keyword/%A5%C1%A5%E5%A1%BC%A5%C8%A5%EA%A5%A2%A5%EB">チュートリアル</a></h2> <p>今回の発表では<a class="keyword" href="https://d.hatena.ne.jp/keyword/JIT">JIT</a><a class="keyword" href="https://d.hatena.ne.jp/keyword/%A5%B3%A5%F3%A5%D1%A5%A4%A5%E9">コンパイラ</a>が書ける人間を増やすことをゴールにしていたが、 30分という短い発表枠内では雰囲気を知ってもらうことにフォーカスし、 実際に手を動かしたい人たちにはそれ用の<a class="keyword" href="https://d.hatena.ne.jp/keyword/%A5%C1%A5%E5%A1%BC%A5%C8%A5%EA%A5%A2%A5%EB">チュートリアル</a>を触ってもらう形を取った。</p> <p><iframe src="https://hatenablog-parts.com/embed?url=https%3A%2F%2Fgithub.com%2Fk0kubun%2Fruby-jit-challenge" title="GitHub - k0kubun/ruby-jit-challenge: Tutorial to write a Ruby JIT" class="embed-card embed-webcard" scrolling="no" frameborder="0" style="display: block; width: 100%; height: 155px; max-width: 500px; margin: 10px 0px;" loading="lazy"></iframe><cite class="hatena-citation"><a href="https://github.com/k0kubun/ruby-jit-challenge">github.com</a></cite></p> <h3 id="JITコンパイラは実は初心者向き"><a class="keyword" href="https://d.hatena.ne.jp/keyword/JIT">JIT</a><a class="keyword" href="https://d.hatena.ne.jp/keyword/%A5%B3%A5%F3%A5%D1%A5%A4%A5%E9">コンパイラ</a>は実は初心者向き</h3> <p>独学で<a class="keyword" href="https://d.hatena.ne.jp/keyword/%A5%B3%A5%F3%A5%D1%A5%A4%A5%E9">コンパイラ</a>の作り方を学ぶ人は、C<a class="keyword" href="https://d.hatena.ne.jp/keyword/%A5%B3%A5%F3%A5%D1%A5%A4%A5%E9">コンパイラ</a>などを実装することが多いように思う。 <a class="keyword" href="https://d.hatena.ne.jp/keyword/C%B8%C0%B8%EC">C言語</a>は実装対象として一見シンプルそうに見えて実は結構機能が多いので、C11をゴールに始めてもC89の範囲すら実装しきらないままエターなる人も多いのではないか。</p> <p>そんな僕みたいな堕落した人間にお勧めなのが<a class="keyword" href="https://d.hatena.ne.jp/keyword/JIT">JIT</a><a class="keyword" href="https://d.hatena.ne.jp/keyword/%A5%B3%A5%F3%A5%D1%A5%A4%A5%E9">コンパイラ</a>。 <a class="keyword" href="https://d.hatena.ne.jp/keyword/%A5%A4%A5%F3%A5%BF%A5%D7%A5%EA%A5%BF">インタプリタ</a>と併走する特性上、実装が面倒な入力は全て<a class="keyword" href="https://d.hatena.ne.jp/keyword/%A5%A4%A5%F3%A5%BF%A5%D7%A5%EA%A5%BF">インタプリタ</a>に移譲することで、限られた労力で最適化と互換性を両立できる。 この<a class="keyword" href="https://d.hatena.ne.jp/keyword/%A5%EA%A5%DD%A5%B8%A5%C8%A5%EA">リポジトリ</a>で作った<a class="keyword" href="https://d.hatena.ne.jp/keyword/JIT">JIT</a><a class="keyword" href="https://d.hatena.ne.jp/keyword/%A5%B3%A5%F3%A5%D1%A5%A4%A5%E9">コンパイラ</a>をベースに、<a class="keyword" href="https://d.hatena.ne.jp/keyword/Rails">Rails</a>アプリを動かしても壊れないような修正をいれることは難しくない。</p> <h3 id="YJITより速いJITを書くという体験">YJITより速い<a class="keyword" href="https://d.hatena.ne.jp/keyword/JIT">JIT</a>を書くという体験</h3> <p><a class="keyword" href="https://d.hatena.ne.jp/keyword/JIT">JIT</a><a class="keyword" href="https://d.hatena.ne.jp/keyword/%A5%B3%A5%F3%A5%D1%A5%A4%A5%E9">コンパイラ</a>を書いていて一番楽しいのは、やはり自分が書いた実装が既存の実装を打ち負かした瞬間だと思う。 フィボナッチは個人<a class="keyword" href="https://d.hatena.ne.jp/keyword/JIT">JIT</a>開発者界隈でよく<a class="keyword" href="https://d.hatena.ne.jp/keyword/%A5%D9%A5%F3%A5%C1%A5%DE%A1%BC%A5%AF">ベンチマーク</a>に使われるのだが、 今回の<a class="keyword" href="https://d.hatena.ne.jp/keyword/%A5%C1%A5%E5%A1%BC%A5%C8%A5%EA%A5%A2%A5%EB">チュートリアル</a>でもこれで他の<a class="keyword" href="https://d.hatena.ne.jp/keyword/JIT">JIT</a>と競う体験をしてもらうことにフォーカスした。 <a class="keyword" href="https://d.hatena.ne.jp/keyword/%A5%EA%A5%DD%A5%B8%A5%C8%A5%EA">リポジトリ</a>内のヒントを素直に辿るだけで、YJITより速い<a class="keyword" href="https://d.hatena.ne.jp/keyword/JIT">JIT</a>を完成させる喜びが体験ができるようになっている。</p> <p>フィボナッチ"だけ"をめちゃくちゃ速くする<a class="keyword" href="https://d.hatena.ne.jp/keyword/%A5%B3%A5%F3%A5%D1%A5%A4%A5%E9">コンパイラ</a>は書こうと思えば比較的短期間で書けるのだが、 それなりに複雑になる反面、<a class="keyword" href="https://d.hatena.ne.jp/keyword/Rails">Rails</a>アプリのような大きな<a class="keyword" href="https://d.hatena.ne.jp/keyword/%A5%D9%A5%F3%A5%C1%A5%DE%A1%BC%A5%AF">ベンチマーク</a>ではその成果が労力に見合わなくなることが多い。 YJITはマイクロベンチを速くすることにプライオリティを置いていないため、今でも簡単に負かすことができるが、 その一方で<a class="keyword" href="https://d.hatena.ne.jp/keyword/Rails">Rails</a>をYJITより速くする<a class="keyword" href="https://d.hatena.ne.jp/keyword/JIT">JIT</a>を書くのは難しい。</p> <h2 id="参照実装を公開した">参照実装を公開した</h2> <p>元々Shopify社内で内部公開していて、自分のアカウントに移すときに参照実装のブランチをpushし忘れてリンク切れになっていたのだが、今は直っている。 どうにもバグが直せなくてギブアップという人や、動くものをとりあえず触ってみたいという方はどうぞ。</p> <p><iframe src="https://hatenablog-parts.com/embed?url=https%3A%2F%2Fgithub.com%2Fk0kubun%2Fruby-jit-challenge%2Ftree%2Fk0kubun" title="GitHub - k0kubun/ruby-jit-challenge at k0kubun" class="embed-card embed-webcard" scrolling="no" frameborder="0" style="display: block; width: 100%; height: 155px; max-width: 500px; margin: 10px 0px;" loading="lazy"></iframe><cite class="hatena-citation"><a href="https://github.com/k0kubun/ruby-jit-challenge/tree/k0kubun">github.com</a></cite></p> <h3 id="opt_send_without_blockとbranchunless">opt_send_without_blockとbranchunless</h3> <p>@HKDnet さんが<a href="https://twitter.com/HKDnet/status/1658101124434644992">ツイート</a>していたが、opt_send_without_blockとbranchunlessのところは他よりやや難易度が高くなっている。 前者は<a class="keyword" href="https://d.hatena.ne.jp/keyword/Ruby">Ruby</a>のメソッド呼び出しをある種自力で実装しなければならず、後者はCFG (制御フローグラフ) を作ったり循環参照のあるコード生成をしたりということが必要になるからだ。</p> <p>どちらも自分で頭をひねって実装してみるのは面白い題材なのでそのままにしてあるが、難易度の傾斜的には、この二つは一旦参照実装を理解してもらって、自分の書き方で実装し直してもらうくらいがちょうどいい気がする。</p> <h2 id="アセンブラを書きたい人へ"><a class="keyword" href="https://d.hatena.ne.jp/keyword/%A5%A2%A5%BB%A5%F3%A5%D6%A5%E9">アセンブラ</a>を書きたい人へ</h2> <p>本当はRubyKaigiの発表内で<a href="https://en.wikipedia.org/wiki/ModR/M">ModR/M</a>の<a class="keyword" href="https://d.hatena.ne.jp/keyword/%A5%A8%A5%F3%A5%B3%A1%BC%A5%C7%A5%A3%A5%F3%A5%B0">エンコーディング</a>とかも解説したかったのだが、いくらコアな参加者が多いRubyKaigiといえど流石にやりすぎという気もしたのと、<a class="keyword" href="https://d.hatena.ne.jp/keyword/%A5%C8%A1%BC%A5%AF">トーク</a>の尺やスライドの準備的にも面倒だったので、<a href="https://hikalium.github.io/opv86/">opv86</a>だけ紹介してわかったつもりになってもらう形を取った。 そこもやってみたい! という人は、<code>lib/jit/assembler.rb</code> を削除して、<a href="https://ja.tech.jar.jp/x86/encode.html">このサイト</a>とかを参考に一から実装してみるのが良いと思う。</p> <h2 id="困ったら">困ったら</h2> <p><a class="keyword" href="https://d.hatena.ne.jp/keyword/Twitter">Twitter</a> <a href="https://twitter.com/k0kubun">@k0kubun</a> にリプライをいただくか <a href="https://ruby-jp.github.io/">ruby-jp Slack</a>の #<a class="keyword" href="https://d.hatena.ne.jp/keyword/ruby">ruby</a>-hacking とかで質問していただければ、解説やアド<a class="keyword" href="https://d.hatena.ne.jp/keyword/%A5%D0%A5%A4%A5%B9">バイス</a>などできる予定。</p> k0kubun Mojoは「C言語のように速いPython」なのか hatenablog://entry/4207575160646451841 2023-05-06T14:15:01+09:00 2023-05-06T16:50:07+09:00 LLVMやSwiftを作ったChris LattnerがCEOをやっている会社が、Pythonの使用感とC言語並の性能を併せ持つ言語としてMojoをアナウンスした。 まだ手元で試せる状態でリリースされてはいないが、最大35000倍Pythonより速いという。 Mojo🔥 combines the usability of Python with the performance of C, unlocking unparalleled programmability of AI hardware and extensibility of AI models. Also, it's up to 3… <p><a class="keyword" href="https://d.hatena.ne.jp/keyword/LLVM">LLVM</a>やSwiftを作ったChris LattnerがCEOをやっている会社が、<a class="keyword" href="https://d.hatena.ne.jp/keyword/Python">Python</a>の使用感と<a class="keyword" href="https://d.hatena.ne.jp/keyword/C%B8%C0%B8%EC">C言語</a>並の性能を併せ持つ言語として<a href="https://www.modular.com/mojo">Mojo</a>をアナウンスした。 まだ手元で試せる状態でリリースされてはいないが、最大35000倍<a class="keyword" href="https://d.hatena.ne.jp/keyword/Python">Python</a>より速いという。</p> <p><blockquote data-conversation="none" class="twitter-tweet" data-lang="en"><p lang="en" dir="ltr"><a class="keyword" href="https://d.hatena.ne.jp/keyword/Mojo">Mojo</a>🔥 combines the usability of <a class="keyword" href="https://d.hatena.ne.jp/keyword/Python">Python</a> with the performance of C, unlocking unparalleled programmability of AI hardware and extensibility of AI models. <br><br>Also, it&#39;s up to 35000x faster than <a class="keyword" href="https://d.hatena.ne.jp/keyword/Python">Python</a> 🤯 and … deploys 🏎 <a href="https://t.co/tjT09U4F80">pic.twitter.com/tjT09U4F80</a></p>&mdash; Modular (@Modular_AI) <a href="https://twitter.com/Modular_AI/status/1653436642248781825?ref_src=twsrc%5Etfw">May 2, 2023</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script> </p> <p>僕は大学院の<a class="keyword" href="https://d.hatena.ne.jp/keyword/%A5%C7%A5%A3%A1%BC%A5%D7%A5%E9%A1%BC%A5%CB%A5%F3%A5%B0">ディープラーニング</a>の授業や仕事などで<a class="keyword" href="https://d.hatena.ne.jp/keyword/Python">Python</a>はある程度使った経験があり、<a class="keyword" href="https://d.hatena.ne.jp/keyword/Python">Python</a>に似た性能特性を持つ<a class="keyword" href="https://d.hatena.ne.jp/keyword/Ruby">Ruby</a>の<a class="keyword" href="https://d.hatena.ne.jp/keyword/JIT">JIT</a><a class="keyword" href="https://d.hatena.ne.jp/keyword/%A5%B3%A5%F3%A5%D1%A5%A4%A5%E9">コンパイラ</a>を書く仕事をしているので、<a class="keyword" href="https://d.hatena.ne.jp/keyword/Mojo">Mojo</a>の何が<a class="keyword" href="https://d.hatena.ne.jp/keyword/C%B8%C0%B8%EC">C言語</a>並に速いのか興味を持った。<a class="keyword" href="https://d.hatena.ne.jp/keyword/Mojo">Mojo</a>の<a href="https://www.youtube.com/watch?v=6GvB5lZJqcE">ローンチ動画</a>や<a href="https://docs.modular.com/mojo/">ドキュメント</a>を見てわかったことをまとめておく。</p> <h2 id="どんな言語なのか">どんな言語なのか</h2> <h3 id="Pythonとの互換性"><a class="keyword" href="https://d.hatena.ne.jp/keyword/Python">Python</a>との互換性</h3> <p><a class="keyword" href="https://d.hatena.ne.jp/keyword/Mojo">Mojo</a>には<a class="keyword" href="https://d.hatena.ne.jp/keyword/Python">Python</a>にはない機能がいろいろとあるが、<a href="https://www.youtube.com/watch?v=6GvB5lZJqcE">ローンチ動画</a>では全く同じコードがCPythonと<a class="keyword" href="https://d.hatena.ne.jp/keyword/Mojo">Mojo</a>の両方で動くことが何度か紹介された。これはつまり、単に<a class="keyword" href="https://d.hatena.ne.jp/keyword/Mojo">Mojo</a>が<a class="keyword" href="https://d.hatena.ne.jp/keyword/Python">Python</a>の資産を使えるだけでなく、<a class="keyword" href="https://d.hatena.ne.jp/keyword/Mojo">Mojo</a>が<a class="keyword" href="https://d.hatena.ne.jp/keyword/Python">Python</a>のスーパーセット言語であることをアピールしたいように見える。<a class="keyword" href="https://d.hatena.ne.jp/keyword/Python">Python</a>に対する<a class="keyword" href="https://d.hatena.ne.jp/keyword/Mojo">Mojo</a>の関係は、<a class="keyword" href="https://d.hatena.ne.jp/keyword/Java">Java</a>に対するKotlinではなく、<a class="keyword" href="https://d.hatena.ne.jp/keyword/JavaScript">JavaScript</a>に対するTypeScriptのようなものということになる。</p> <p>一方、<a href="https://docs.modular.com/mojo/why-mojo.html">Why Mojo</a>のあたりを見ていると、現状の互換性は散々で、クラスもサポートしてないみたいな状態らしい。彼らはスタートアップ企業であるから、お金や人を継続的に惹きつけるために多少の誇大広告が必要なのは理解できるが、現時点でリリースに至ってないのはまだ実際には<a class="keyword" href="https://d.hatena.ne.jp/keyword/Python">Python</a>のスーパーセットにはほど遠い状態であるからと推察できる。Python3との互換性のためにCPythonを活用しているというよくわからない説明があるが、<a class="keyword" href="https://d.hatena.ne.jp/keyword/Python">Python</a>モジュールのインポートが普通のimport文ではなく <code>Python.import_module</code> なのはこれがCPythonそのものを呼び出して相互に動作させているからかなと思った。</p> <p>とはいえ、Python2からのPython3移行の例を引き合いに出して、<a class="keyword" href="https://d.hatena.ne.jp/keyword/Python">Python</a>のサブセットを実装することで<a class="keyword" href="https://d.hatena.ne.jp/keyword/Python">Python</a>の弱点を解消するのは既存の<a class="keyword" href="https://d.hatena.ne.jp/keyword/Python">Python</a>資産という強みを生かせないのでダメなんだと力説しているので、少なくともPython3のライブラリが使えて、運が良ければ本当に<a class="keyword" href="https://d.hatena.ne.jp/keyword/Python">Python</a>のスーパーセット言語として出てくるのではないかという雰囲気はある。</p> <h3 id="Rust風の言語機能">Rust風の言語機能</h3> <p>Rustのようにモダンな言語仕様かつ速い<a class="keyword" href="https://d.hatena.ne.jp/keyword/%C6%B0%C5%AA%B8%C0%B8%EC">動的言語</a>が欲しい、みたいな言説を<a class="keyword" href="https://d.hatena.ne.jp/keyword/Twitter">Twitter</a>で時おり見かけるのだが、<a class="keyword" href="https://d.hatena.ne.jp/keyword/Mojo">Mojo</a>はこの領域を攻めているように感じる。<a class="keyword" href="https://d.hatena.ne.jp/keyword/Mojo">Mojo</a>はキャッチフレーズがAI開発向けの言語であるのと同時に、<a href="https://docs.modular.com/mojo/faq.html">FAQ</a>では<a class="keyword" href="https://d.hatena.ne.jp/keyword/Mojo">Mojo</a>は汎用<a class="keyword" href="https://d.hatena.ne.jp/keyword/%A5%D7%A5%ED%A5%B0%A5%E9%A5%DF%A5%F3%A5%B0%B8%C0%B8%EC">プログラミング言語</a>であると説明されている。</p> <p>Rustは所有権といったセマンティクスが常に強制されるので、書いて<a class="keyword" href="https://d.hatena.ne.jp/keyword/%A5%B3%A5%F3%A5%D1%A5%A4%A5%EB">コンパイル</a>を通すのが面倒なことがまあまああるのだが、それらの手間をかけてスレッドセーフティや性能を追求しなくとも、アプリの特性上それが問題にならない場面はよくある。そういう場面では何の型<a class="keyword" href="https://d.hatena.ne.jp/keyword/%A5%A2%A5%CE%A5%C6%A1%BC%A5%B7%A5%E7%A5%F3">アノテーション</a>もない普通の<a class="keyword" href="https://d.hatena.ne.jp/keyword/Python">Python</a>を書き、局所的に性能が必要な部分だけ<a class="keyword" href="https://d.hatena.ne.jp/keyword/Mojo">Mojo</a>の高速な書き方を使いたいみたいな<a class="keyword" href="https://d.hatena.ne.jp/keyword/%A5%E6%A1%BC%A5%B9%A5%B1%A1%BC%A5%B9">ユースケース</a>は存在するように思う。</p> <p><code>let</code> でイミュータブルな変数を宣言したり、所有権や参照の概念があったりする。<code>def</code> で関数を宣言するといままで通りの<a class="keyword" href="https://d.hatena.ne.jp/keyword/Python">Python</a>のコードが動くのに対し、<code>fn</code> で関数を宣言すると型宣言が強制され、全てのローカル変数や例外の明示的宣言が必須になる。書くのは面倒になると思うが、おそらくこれを使うと<a class="keyword" href="https://d.hatena.ne.jp/keyword/%A5%B3%A5%F3%A5%D1%A5%A4%A5%E9">コンパイラ</a>は高速化がしやすくなるので、書きやすさと保守性や性能のバランスをユーザーが選択できることになる。</p> <h3 id="デプロイ容易性">デプロイ容易性</h3> <p>素の<a class="keyword" href="https://d.hatena.ne.jp/keyword/Python">Python</a>ではダメだったモチベーションの一つに、モバイルやサーバー環境でのデプロイが困難であったことが挙げられている。サイズは何十MBにもなってしまうが、ランタイムを内包したバイナリを生成できるらしい。最近Node.jsがそれをやっている話が流れてきたが、これに関してはCPythonもやればできるのではという気もしないでもない。僕は<a href="https://github.com/mooz/percol">percol</a>よりは<a href="https://github.com/peco/peco">peco</a>、<a href="https://github.com/mooz/xkeysnail">xkeysnail</a>よりは<a href="https://github.com/k0kubun/xremap">xremap</a>の方が便利だと思っているが、それは<a class="keyword" href="https://d.hatena.ne.jp/keyword/Python">Python</a>を独立してインストールして維持しないといけないのが面倒くさいからで、シングルバイナリのデプロイが生活を少し楽にしてくれることはよくわかる。</p> <h2 id="なぜ速いのか">なぜ速いのか</h2> <p>巷では<a class="keyword" href="https://d.hatena.ne.jp/keyword/Mojo">Mojo</a>がまるで<a class="keyword" href="https://d.hatena.ne.jp/keyword/C%B8%C0%B8%EC">C言語</a>並みに速い<a class="keyword" href="https://d.hatena.ne.jp/keyword/Python">Python</a>処理系であるかのような受け取り方をしている人が見受けられるが、ローンチ動画を見た限りでは、単に<a class="keyword" href="https://d.hatena.ne.jp/keyword/Python">Python</a>処理系として使うとCPythonの数倍速い程度に留まり、<a class="keyword" href="https://d.hatena.ne.jp/keyword/C%B8%C0%B8%EC">C言語</a>の性能には程遠い印象を受ける。しかし、何も書き変えずに数倍速くなるのはそもそも偉いし、<a class="keyword" href="https://d.hatena.ne.jp/keyword/Python">Python</a>風の<a class="keyword" href="https://d.hatena.ne.jp/keyword/%B9%E2%B5%E9%B8%C0%B8%EC">高級言語</a>にちょっと書き直すと35000倍速くなるのも普通にすごい話なので、それに貢献していると思われるポイントをまとめてみた。</p> <h3 id="MLIRとSIMD並列化">MLIRと<a class="keyword" href="https://d.hatena.ne.jp/keyword/SIMD">SIMD</a>、並列化</h3> <p>端的にいうと、<a class="keyword" href="https://d.hatena.ne.jp/keyword/Mojo">Mojo</a>というのは高速な<a class="keyword" href="https://d.hatena.ne.jp/keyword/Python">Python</a>なのではなく、MLIRという並列計算に長けた<a class="keyword" href="https://d.hatena.ne.jp/keyword/%A5%B3%A5%F3%A5%D1%A5%A4%A5%E9">コンパイラ</a>基盤を言語機能として表出させ、<a class="keyword" href="https://d.hatena.ne.jp/keyword/Python">Python</a>風の<a class="keyword" href="https://d.hatena.ne.jp/keyword/%B9%E2%B5%E9%B8%C0%B8%EC">高級言語</a>で簡単に扱えるようにすることでCや<a class="keyword" href="https://d.hatena.ne.jp/keyword/C%2B%2B">C++</a>より速いコードが書ける言語、という感じに見える。<a class="keyword" href="https://d.hatena.ne.jp/keyword/%A5%DE%A5%F3%A5%C7%A5%EB%A5%D6%A5%ED">マンデルブロ</a>ットが35000倍速くなるのは<a class="keyword" href="https://d.hatena.ne.jp/keyword/Mojo">Mojo</a>の<a class="keyword" href="https://d.hatena.ne.jp/keyword/SIMD">SIMD</a>サポートを使っているからだとローンチ動画で説明されており、この<a class="keyword" href="https://d.hatena.ne.jp/keyword/SIMD">SIMD</a>は<a class="keyword" href="https://d.hatena.ne.jp/keyword/Mojo">Mojo</a>がMLIRを直接使えることで実現されているとドキュメントに書いてある。</p> <p><a href="https://conf.researchr.org/series/cgo">CGO</a>というコード最適化に関するカンファレンスの論文を眺めている時に、Chris Lattnerが書いた<a href="https://research.google/pubs/pub49988/">MLIRの論文</a>を見かけたことがある。<a class="keyword" href="https://d.hatena.ne.jp/keyword/LLVM">LLVM</a>の作者である彼は、最近は<a class="keyword" href="https://d.hatena.ne.jp/keyword/LLVM">LLVM</a>よりMLIRの方に注力していると伺える。<a class="keyword" href="https://d.hatena.ne.jp/keyword/Google">Google</a>でMLIRを作ったが、MLIRを使いやすい言語がないから起業して言語作っちゃうぞ、ということだったらカッコイイなと思う<a href="#f-8f46f786" name="fn-8f46f786" title="実際にはどういうモチベーションで起業したのかは調べてない">*1</a>。</p> <p>MLIRのMLはMachine LearningではなくMulti-Levelの略なのだが、MLIRには特定の<a class="keyword" href="https://d.hatena.ne.jp/keyword/%A5%A2%A1%BC%A5%AD%A5%C6%A5%AF%A5%C1%A5%E3">アーキテクチャ</a>や環境に特化した最適化を可能にするdialectという概念があり、それを使って<a class="keyword" href="https://d.hatena.ne.jp/keyword/SIMD">SIMD</a>やスレッドで並列計算することができ、<a class="keyword" href="https://d.hatena.ne.jp/keyword/LLVM">LLVM</a>と違ってMachine Learningといった<a class="keyword" href="https://d.hatena.ne.jp/keyword/%A5%C9%A5%E1%A5%A4%A5%F3">ドメイン</a>固有の最適化も可能にしていると論文に書いてある。</p> <h3 id="動的な機能が制限されたstruct">動的な機能が制限されたstruct</h3> <p>次に重要そうだなと思ったのがstruct。言語機能的にはdataclassのようなものだし特段驚くようなものではないが、このstructを使うと動的なディスパッチやモンキーパッチが不可能になると書いてある。このstructを使った変数を宣言して、その変数に対してstructが実装していない処理をしようとすると<a class="keyword" href="https://d.hatena.ne.jp/keyword/%A5%B3%A5%F3%A5%D1%A5%A4%A5%EB">コンパイル</a>時エラーになる例が示されており、メソッドの呼び出し先が静的に解決できるのは最適化目線では非常に素晴らしいことだなと思う。</p> <h3 id="AOTとJITをサポート">AOTと<a class="keyword" href="https://d.hatena.ne.jp/keyword/JIT">JIT</a>をサポート</h3> <p>僕は<a class="keyword" href="https://d.hatena.ne.jp/keyword/JIT">JIT</a>屋さんなので、<a class="keyword" href="https://d.hatena.ne.jp/keyword/Mojo">Mojo</a>の話を聞いた時に<a class="keyword" href="https://d.hatena.ne.jp/keyword/Python">Python</a>部分は<a class="keyword" href="https://d.hatena.ne.jp/keyword/JIT">JIT</a>してるのかなというところが最初に気になったが、FAQを見るとAOTと<a class="keyword" href="https://d.hatena.ne.jp/keyword/JIT">JIT</a>を両方サポートしていると書いてある。<a class="keyword" href="https://d.hatena.ne.jp/keyword/Python">Python</a>のコードをそのまま<a class="keyword" href="https://d.hatena.ne.jp/keyword/Mojo">Mojo</a>で実行して8.59倍速になってるところは、MLIRの基盤の寄与が大きいのか言語特有の<a class="keyword" href="https://d.hatena.ne.jp/keyword/JIT">JIT</a>サポートががんばってるのかどっちなのかはわからないが、structではない(動的ディスパッチが可能な)既存の<a class="keyword" href="https://d.hatena.ne.jp/keyword/Python">Python</a>ライブラリのクラスをこねくり回すところでまともな性能を出したかったら、実行時情報に特化して最適化を行なう<a class="keyword" href="https://d.hatena.ne.jp/keyword/JIT">JIT</a>は必須であろうと思われる。CPythonもそろそろ本気を出して欲しい。</p> <h2 id="所感">所感</h2> <p><a class="keyword" href="https://d.hatena.ne.jp/keyword/Mojo">Mojo</a>がCPythonの用途を全て置き換えていくかというとそうはならないと思うが、<a class="keyword" href="https://d.hatena.ne.jp/keyword/Python">Python</a>の既存資産が使えて、AI開発のために高速なコードが書けるというのはいいものだと思うし、何より<a class="keyword" href="https://d.hatena.ne.jp/keyword/LLVM">LLVM</a>やSwiftを作ったChris Lattnerがやっているというのがアツいところなので、正式リリースに期待している。</p> <p>言語の使用感としては<a class="keyword" href="https://d.hatena.ne.jp/keyword/Ruby">Ruby</a>の方が好きなので僕は<a class="keyword" href="https://d.hatena.ne.jp/keyword/Ruby">Ruby</a>を速くして使っていくが、最適化のところで真似できるア<a class="keyword" href="https://d.hatena.ne.jp/keyword/%A5%A4%A5%C7%A5%A2">イデア</a>があったら参考にしていきたい。</p> <div class="footnote"> <p class="footnote"><a href="#fn-8f46f786" name="f-8f46f786" class="footnote-number">*1</a><span class="footnote-delimiter">:</span><span class="footnote-text">実際にはどういうモチベーションで起業したのかは調べてない</span></p> </div> k0kubun RJIT: RubyでRubyのJITコンパイラを書いた hatenablog://entry/4207112889978548692 2023-04-06T17:16:43+09:00 2023-04-07T11:02:10+09:00 僕はRustでRubyのJITを書く仕事をしているのだが、去年の12月くらいから、趣味ではRubyでRubyのJITを書いている。 それまではC言語でコード生成を行なうMJITを5年くらいメンテしていたのだが、先月、Rubyで機械語を直接アセンブルするRJITに差し替えた。 github.com なので、今Rubyのmasterブランチには、会社で業務として開発しているRust製のYJITと、僕が趣味で開発しているRuby製のRJITの2つのJITコンパイラが存在している。余談だが、JITの開発をしすぎてRubyの作者であるまつもとさんのコミット数を最近抜いた。 なぜMJITをやめたのか MJ… <p>僕はRustで<a class="keyword" href="https://d.hatena.ne.jp/keyword/Ruby">Ruby</a>の<a class="keyword" href="https://d.hatena.ne.jp/keyword/JIT">JIT</a>を書く仕事をしているのだが、去年の12月くらいから、趣味では<a class="keyword" href="https://d.hatena.ne.jp/keyword/Ruby">Ruby</a>で<a class="keyword" href="https://d.hatena.ne.jp/keyword/Ruby">Ruby</a>の<a class="keyword" href="https://d.hatena.ne.jp/keyword/JIT">JIT</a>を書いている。 それまでは<a class="keyword" href="https://d.hatena.ne.jp/keyword/C%B8%C0%B8%EC">C言語</a>でコード生成を行なうMJITを5年くらいメンテしていたのだが、先月、<a class="keyword" href="https://d.hatena.ne.jp/keyword/Ruby">Ruby</a>で<a class="keyword" href="https://d.hatena.ne.jp/keyword/%B5%A1%B3%A3%B8%EC">機械語</a>を直接<a class="keyword" href="https://d.hatena.ne.jp/keyword/%A5%A2%A5%BB%A5%F3%A5%D6%A5%EB">アセンブル</a>するRJITに差し替えた。</p> <p><iframe src="https://hatenablog-parts.com/embed?url=https%3A%2F%2Fgithub.com%2Fruby%2Fruby%2Fpull%2F7448" title="RJIT by k0kubun · Pull Request #7448 · ruby/ruby" class="embed-card embed-webcard" scrolling="no" frameborder="0" style="display: block; width: 100%; height: 155px; max-width: 500px; margin: 10px 0px;" loading="lazy"></iframe><cite class="hatena-citation"><a href="https://github.com/ruby/ruby/pull/7448">github.com</a></cite></p> <p>なので、今<a class="keyword" href="https://d.hatena.ne.jp/keyword/Ruby">Ruby</a>のmasterブランチには、会社で業務として開発しているRust製のYJITと、僕が趣味で開発している<a class="keyword" href="https://d.hatena.ne.jp/keyword/Ruby">Ruby</a>製のRJITの2つの<a class="keyword" href="https://d.hatena.ne.jp/keyword/JIT">JIT</a><a class="keyword" href="https://d.hatena.ne.jp/keyword/%A5%B3%A5%F3%A5%D1%A5%A4%A5%E9">コンパイラ</a>が存在している。余談だが、<a class="keyword" href="https://d.hatena.ne.jp/keyword/JIT">JIT</a>の開発をしすぎて<a class="keyword" href="https://d.hatena.ne.jp/keyword/Ruby">Ruby</a>の作者であるまつもとさんのコミット数を最近抜いた。</p> <p><span itemscope itemtype="http://schema.org/Photograph"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/k/k0kubun/20230406/20230406171605.png" width="1200" height="378" loading="lazy" title="" class="hatena-fotolife" itemprop="image"></span></p> <h1 id="なぜMJITをやめたのか">なぜMJITをやめたのか</h1> <p>MJITも結構がんばっていて、去年開発していた<a class="keyword" href="https://d.hatena.ne.jp/keyword/Ruby">Ruby</a> 3.2ではMJITの<a class="keyword" href="https://d.hatena.ne.jp/keyword/%A5%B3%A5%F3%A5%D1%A5%A4%A5%E9">コンパイラ</a>の実装をCから<a class="keyword" href="https://d.hatena.ne.jp/keyword/Ruby">Ruby</a>に<a class="keyword" href="https://d.hatena.ne.jp/keyword/%A5%D5%A5%EB%A5%B9%A5%AF%A5%E9%A5%C3%A5%C1">フルスクラッチ</a>した上、バックグラウンド処理をpthreadからfork + SIGCHLDで行なうように変えたり、早い段階から<a class="keyword" href="https://d.hatena.ne.jp/keyword/%A5%B3%A5%F3%A5%D1%A5%A4%A5%EB">コンパイル</a>を可能な限りまとめて<a class="keyword" href="https://d.hatena.ne.jp/keyword/%A5%D0%A5%C3%A5%C1%BD%E8%CD%FD">バッチ処理</a>してwarmupを高速化するなど、結構手を加えていた。</p> <p>しかし、MJITの改善について考えれば考えるほど、生成コードが<a class="keyword" href="https://d.hatena.ne.jp/keyword/C%B8%C0%B8%EC">C言語</a>に縛られているせいでコードの動的書き換えを前提とした最適化が難しいことが気になってしまった。そこで、12/10に<a href="https://github.com/ruby/ruby/pull/6900">MJITのコンパイルのバッチ化</a>をマージした次の日から、その問題を抱えていない設計を持つRJITに着手し始め、3ヶ月ほどかけて公開に至った。</p> <h1 id="RJITでやりたいこと">RJITでやりたいこと</h1> <p>MJITの<a class="keyword" href="https://d.hatena.ne.jp/keyword/%A5%B3%A5%F3%A5%D1%A5%A4%A5%E9">コンパイラ</a>が<a class="keyword" href="https://d.hatena.ne.jp/keyword/Ruby">Ruby</a>になったことで、<a class="keyword" href="https://d.hatena.ne.jp/keyword/Ruby">Ruby</a> 3.2からモンキーパッチを使った<a class="keyword" href="https://d.hatena.ne.jp/keyword/JIT">JIT</a><a class="keyword" href="https://d.hatena.ne.jp/keyword/%A5%B3%A5%F3%A5%D1%A5%A4%A5%E9">コンパイラ</a>の差し替えが可能になった。これを使って<a class="keyword" href="https://d.hatena.ne.jp/keyword/JIT">JIT</a>を開発している人が2人いて、この<a class="keyword" href="https://d.hatena.ne.jp/keyword/%A5%D0%A5%C3%A5%AF%A5%C9%A5%A2">バックドア</a>を残すことがRJITの主目的の一つである。僕もその2人もYJITの開発に参加している<a href="#f-4cc264d2" name="fn-4cc264d2" title="ちなみにその2人はRubyとRailsの両方のコミッタでもある">*1</a>ので、オリジナルの<a class="keyword" href="https://d.hatena.ne.jp/keyword/JIT">JIT</a>開発の経験をYJITにフィードバックするのが最終的な狙い。YJITを越えるのは特にゴールではないため、本番環境では引き続きYJITを使うことが推奨される。</p> <p>YJITの開発では<a class="keyword" href="https://d.hatena.ne.jp/keyword/%A5%B3%A5%F3%A5%D1%A5%A4%A5%EB">コンパイル</a>速度やメモリ消費量に細心の注意が払われており、<a class="keyword" href="https://d.hatena.ne.jp/keyword/%A5%D9%A5%F3%A5%C1%A5%DE%A1%BC%A5%AF">ベンチマーク</a>の改善に即座に貢献しない複雑な実装はマージしないで塩漬けにする傾向にある。僕は既にYJITのシンプルなメソッドインライン化や<a href="https://speakerdeck.com/eregon/splitting-the-crucial-optimization-for-ruby-blocks">Splitting</a>などのPRを用意したが、これら単体では大きな速度改善に繋らなかったため、マージされなかった。RJITはそういった試験的な実装を継続的に試せる環境にしたいと思っている。実際に成果に繋ったものはYJITにポートするようにしていて、最近もそのようなPRをマージした。</p> <h1 id="RJITのアーキテクチャ">RJITの<a class="keyword" href="https://d.hatena.ne.jp/keyword/%A5%A2%A1%BC%A5%AD%A5%C6%A5%AF%A5%C1%A5%E3">アーキテクチャ</a></h1> <p>MJITはメソッド<a class="keyword" href="https://d.hatena.ne.jp/keyword/JIT">JIT</a>だったが、RJITではYJITの実験場という目的から、YJITと同じく<a href="https://arxiv.org/abs/1411.0352">Lazy Basic Block Versioning</a>というデザインで作られている。それだけでなく、僕自身がYJITの仕組みを学びたいという目的もあり、<a class="keyword" href="https://d.hatena.ne.jp/keyword/codegen">codegen</a>もほぼYJITの実装をなぞって作ってあるため、Yet Another YJITみたいな状態になっている。</p> <p>一方で、<a href="https://github.com/ruby/ruby/blob/70371aa0713d5de190fcd7e4d42dbca6bfe1da60/lib/ruby_vm/rjit/assembler.rb">アセンブラ</a>に関しては誰の実装も見ずに完全に自力で書き上げた。これは何というか、これまで<a class="keyword" href="https://d.hatena.ne.jp/keyword/C%B8%C0%B8%EC">C言語</a>に依存してコード生成をしていたので "本物の" <a class="keyword" href="https://d.hatena.ne.jp/keyword/JIT">JIT</a><a class="keyword" href="https://d.hatena.ne.jp/keyword/%A5%B3%A5%F3%A5%D1%A5%A4%A5%E9">コンパイラ</a>を書いているという感覚がなかったので、<a class="keyword" href="https://d.hatena.ne.jp/keyword/Intel">Intel</a> SDMを読み込んでここをちゃんと書いたことでそのコンプレックスが今回解消された。</p> <p><a class="keyword" href="https://d.hatena.ne.jp/keyword/%A5%A2%A5%BB%A5%F3%A5%D6%A5%E9">アセンブラ</a>の<a class="keyword" href="https://d.hatena.ne.jp/keyword/API">API</a>はなるべく生成コードに近くなるようにしてあって、例えば以下の<a class="keyword" href="https://d.hatena.ne.jp/keyword/%A5%A2%A5%BB%A5%F3%A5%D6%A5%EA">アセンブリ</a>にあたるコードは、</p> <pre class="code lang-asm" data-lang="asm" data-unlink><span class="synIdentifier">lea</span> <span class="synIdentifier">rax</span>, [<span class="synIdentifier">rbx</span> + <span class="synConstant">8</span>] <span class="synIdentifier">mov</span> <span class="synIdentifier">rdi</span>, <span class="synConstant">0</span> </pre> <p>以下のような<a class="keyword" href="https://d.hatena.ne.jp/keyword/Ruby">Ruby</a> <a class="keyword" href="https://d.hatena.ne.jp/keyword/DSL">DSL</a>で生成できるようになっている。</p> <pre class="code lang-ruby" data-lang="ruby" data-unlink>asm.lea(<span class="synConstant">:rax</span>, [<span class="synConstant">:rbx</span>, <span class="synConstant">8</span>]) asm.mov(<span class="synConstant">:rdi</span>, <span class="synConstant">0</span>) </pre> <p>それから、<a class="keyword" href="https://d.hatena.ne.jp/keyword/Ruby">Ruby</a> 3.2でMJITを<a class="keyword" href="https://d.hatena.ne.jp/keyword/Ruby">Ruby</a>に書き換えるにあたり、Cのstructに<a class="keyword" href="https://d.hatena.ne.jp/keyword/Ruby">Ruby</a>からシームレスにアクセスする仕組みを結構時間をかけて作ったのだが、これはRJITにそのまま引き継いできて便利に使っている。RustのbindgenではCとの連携機能が非常に限られており、例えばstatic inlineの関数は呼び出せないのでYJIT用に手動でラップしないといけなかったり、Cのstructのfield一つごとにそれにアクセスするための関数をYJIT用に用意して使うみたいな感じなのだが、RJITではそもそもそこを自前で作り全自動化することで快適な開発ライフを送っている。</p> <p>例えば、YJITだとこのようなコードがあるが、</p> <pre class="code lang-rust" data-lang="rust" data-unlink><span class="synStatement">let</span> stack_max <span class="synStatement">=</span> <span class="synStatement">unsafe</span> { <span class="synIdentifier">rb_get_iseq_body_stack_max</span>(iseq) }; </pre> <p>RJITだとこうなる。</p> <pre class="code lang-ruby" data-lang="ruby" data-unlink>stack_max = iseq.body.stack_max </pre> <h1 id="RJITのパフォーマンス">RJITのパフォーマンス</h1> <p>1日1回<a class="keyword" href="https://d.hatena.ne.jp/keyword/Ruby">Ruby</a>の<a class="keyword" href="https://d.hatena.ne.jp/keyword/%A5%D9%A5%F3%A5%C1%A5%DE%A1%BC%A5%AF">ベンチマーク</a>を走らせて表示する <a href="https://rubybench.github.io/">rubybench.github.io</a> というサイトをメンテしていて、 このサイトでの最新の結果は以下のようになっている。</p> <p><figure class="figure-image figure-image-fotolife" title="JITなしと比較して何倍速くなったかのグラフ (棒が長い方が速い)"><span itemscope itemtype="http://schema.org/Photograph"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/k/k0kubun/20230406/20230406171155.png" width="1200" height="512" loading="lazy" title="" class="hatena-fotolife" itemprop="image"></span><figcaption><a class="keyword" href="https://d.hatena.ne.jp/keyword/JIT">JIT</a>なしと比較して何倍速くなったかのグラフ (棒が長い方が速い)</figcaption></figure></p> <p>MJITの性能は<a href="https://github.com/ruby/ruby/pull/7448">RJITをマージした時のPR</a>を見て欲しいが、MJITはこれらの<a class="keyword" href="https://d.hatena.ne.jp/keyword/%A5%D9%A5%F3%A5%C1%A5%DE%A1%BC%A5%AF">ベンチマーク</a>では多くの場合<a class="keyword" href="https://d.hatena.ne.jp/keyword/%A5%A4%A5%F3%A5%BF%A5%D7%A5%EA%A5%BF">インタプリタ</a>より遅いという状態だったので、RJITでは (<a class="keyword" href="https://d.hatena.ne.jp/keyword/ruby">ruby</a>-lsp以外は) これだけ高速化できているというのは大分進歩した感じがする。MJITのrailsbenchでの性能は、かなりがんばってチューニングして5%速くなるみたいな感じだったが、RJITでは安定して30%くらい高速化している。</p> <h1 id="セルフホストJIT構想">セルフホスト<a class="keyword" href="https://d.hatena.ne.jp/keyword/JIT">JIT</a>構想</h1> <p>RJITでRJITを<a class="keyword" href="https://d.hatena.ne.jp/keyword/JIT">JIT</a>すると再起呼び出しになったり、ありとあらゆる理由で壊れるので現在はRJITそのものは<a class="keyword" href="https://d.hatena.ne.jp/keyword/%A5%A4%A5%F3%A5%BF%A5%D7%A5%EA%A5%BF">インタプリタ</a>実行になっている。 <a class="keyword" href="https://d.hatena.ne.jp/keyword/%A5%A4%A5%F3%A5%BF%A5%D7%A5%EA%A5%BF">インタプリタ</a>の性能でRust実装のwarmup速度に追いつくのは無理な話だが、RJITの<a class="keyword" href="https://d.hatena.ne.jp/keyword/%A5%B3%A5%F3%A5%D1%A5%A4%A5%E9">コンパイラ</a>が十分に発展したら、 別プロセスでも再利用できるようなコードを生成するモードを用意して、RJIT自体をRJITでプリ<a class="keyword" href="https://d.hatena.ne.jp/keyword/%A5%B3%A5%F3%A5%D1%A5%A4%A5%EB">コンパイル</a>して添付する、 みたいなことを妄想したりしていた。</p> <p>それはそれで面白い取り組みになると思うが、RJITがrailsbenchで生成するコードがYJITとほぼ同等になった今railsbenchでの性能を比べてみると、warmup速度以前にピークタイムもYJITにそこそこ差が開いているという気付きがあった。何か実装漏れがあるとかならわかるが、僕の知る限りrailsbenchに影響しそうなところは全てポートしてきたという理解なので、やや不思議な状態になっている。そこで <code>GC.disable</code> をしてみたところ、性能差がかなり縮まった。そのため、RJITが生成するオブジェクトが<a class="keyword" href="https://d.hatena.ne.jp/keyword/GC">GC</a>に与えるオーバーヘッドがまあまあ大きいということになるが、これにアプローチする方法は今のところ思いついていない。</p> <h1 id="まとめ">まとめ</h1> <p>僕は<a class="keyword" href="https://d.hatena.ne.jp/keyword/Ruby">Ruby</a>の<a class="keyword" href="https://d.hatena.ne.jp/keyword/JIT">JIT</a>を書ける仲間を増やしたいという思いがあり、RubyKaigi 2023ではそういう人を増やすための<a class="keyword" href="https://d.hatena.ne.jp/keyword/%A5%C8%A1%BC%A5%AF">トーク</a>をする予定。松本で僕と握手!</p> <div class="footnote"> <p class="footnote"><a href="#fn-4cc264d2" name="f-4cc264d2" class="footnote-number">*1</a><span class="footnote-delimiter">:</span><span class="footnote-text">ちなみにその2人は<a class="keyword" href="https://d.hatena.ne.jp/keyword/Ruby">Ruby</a>と<a class="keyword" href="https://d.hatena.ne.jp/keyword/Rails">Rails</a>の両方のコミッタでもある</span></p> </div> k0kubun 2022年にやったこと hatenablog://entry/4207112889949230590 2022-12-31T13:40:06+09:00 2023-12-31T14:25:16+09:00 2021年にやったこと 2020年にやったこと 2019年にやったこと 2018年にやったこと 2017年にやったこと 2016年にやったこと 2015年にやったこと 今年のハイライトは 大学院を卒業し、CS修士号を取った グリーンカードを取った Shopifyに転職し、仕事でRubyのJIT開発を始めた という感じの一年だった。 大学 5月にジョージア工科大学のCS修士を卒業した。 ほとんどの人は3~4年かけて卒業するプログラムを、理論上最速である1年9か月で卒業するRTAをやっていた。 かといって特に雑になるでもなく、GPA 3.90/4.00 だったので、GPA 3.36だった学部の時よ… <ul> <li><a href="https://k0kubun.hatenablog.com/entry/2021-summary">2021年にやったこと</a></li> <li><a href="https://k0kubun.hatenablog.com/entry/2020-summary">2020年にやったこと</a></li> <li><a href="https://k0kubun.hatenablog.com/entry/2019-summary">2019年にやったこと</a></li> <li><a href="https://k0kubun.hatenablog.com/entry/2018-summary">2018年にやったこと</a></li> <li><a href="https://k0kubun.hatenablog.com/entry/2017-summary">2017年にやったこと</a></li> <li><a href="https://k0kubun.hatenablog.com/entry/2016-summary">2016年にやったこと</a></li> <li><a href="https://k0kubun.hatenablog.com/entry/2015/12/31/000052">2015年にやったこと</a></li> </ul> <p>今年のハイライトは</p> <ul> <li>大学院を卒業し、CS修士号を取った</li> <li>グリーンカードを取った</li> <li>Shopifyに転職し、仕事でRubyのJIT開発を始めた</li> </ul> <p>という感じの一年だった。</p> <h2 id="大学">大学</h2> <p>5月に<a href="https://k0kubun.hatenablog.com/entry/graduation">ジョージア工科大学のCS修士を卒業した</a>。 ほとんどの人は3~4年かけて卒業するプログラムを、理論上最速である1年9か月で卒業するRTAをやっていた。 かといって特に雑になるでもなく、GPA 3.90/4.00 だったので、GPA 3.36だった学部の時よりかなりマシな成績を取っている。</p> <p>なんかその記事に書くとダサくなりそうなので書かなかったが、よく宿題の提出期限になる月曜の朝5時はほぼ毎週起きててギリギリに提出するくらいには大変だった。4:57~4:59くらいの時間帯で提出した宿題の数は多い。しかも別にダラけててそうなっていたのでもなくて、毎日真面目にやっていても睡眠を削る必要が出てくるくらいのワークロードだった。卒業してからは生活が変わりすぎてすごい昔のことのように感じる。</p> <p>博士は将来的に時間と経済的な余裕ができたら挑戦するかもしれないが、どこかに公開した論文は一つもないままここまで来てしまったので、まずはアカデミックな実績を作っておくところからかなという感じがする。MJITの話は実用性はさておき新規性はある気がするので書いてみたい気がするが、日々コードばかり書いてしまっていて特に準備とかも進められていない。</p> <h2 id="仕事">仕事</h2> <h3 id="Treasure-Data-17月">Treasure Data (1~7月)</h3> <p>年の頭にCTOのnahiさんがテクニカルアーキテクト的なロールを持つグループを発足し、ICと半々くらいでそれを兼務し始めた。 純粋にシステムのことだけを考えるシステムアーキテクトとは違い、テクニカルなこと"も"考えてビジネスのプライオリティを調整するような業務だけど、3つのチームや様々なコンポーネントを転々としたことで得た広めのコンポーネント知識を活かして価値を発揮していくのがやりやすい働き方だったように思う。短い間にどれくらい価値が出せたかはわからないけど、良い経験になった。</p> <p>ICとして何をやっていたかは<a href="https://k0kubun.hatenablog.com/entry/farewell-treasure-data">退職ブログ</a>にも書いたが、 クエリを速くするためにストレージレイヤーを改善する仕事をやらせてもらっていた。 あるワーカーコンポーネントをスクラッチして、とあるマイグレーションを一つ完遂した。 そのコンポーネントがそれとは別の巨大マイグレーションプロジェクトにも一役買う予定のままそれの完成を見ずに退職したが、それが今どんな感じなのか秘かに気になっている。</p> <h3 id="Shopify-712月">Shopify (7~12月)</h3> <p>Shopifyが開発したRubyのJITであるYJITをフルタイムで開発する仕事をし始めた。これまでは仕事で分散システムをやり、趣味で言語処理系をやる生活を送っていたが、仕事も趣味も言語処理系一本に絞っていく生活にシフトした。チーム内に日本語ネイティブの人がいなくて、完全に英語だけで仕事をするようになったことも前職との違いと言えそう。</p> <p>今年やった主な業務としては、Arm移植に結構なVM命令数貢献したのと、不要コードを消すコードGCを僕がリードで開発していたのと、 本番で使えるメトリクスの拡充を行ない本番アプリにRuby masterを出してYJITのチューニングをやっていたという感じ。 Ruby masterを本番に出してチューニングする業務を始めるまでの最初3か月くらいはプロプライエタリなコードは1行も書いてなかったが、今ではYJITのバージョンアップやチューニングコミットだけで業務アプリにコミット数をまあまあ積んでいる人になった。</p> <p><a href="https://twitter.com/tobi/status/1605656985185226753">CEOが書いた</a>ので公開情報だが、お客様のストアをレンダリングする、社内で最もトラフィックが多いコンポーネントほぼ全台でYJITが有効になっており、同コンポーネント上でRuby masterのYJITなし/あり同士で公平に速度比較をしている環境ではYJITにより<a href="https://twitter.com/paracycle/status/1605706245955997697">5~10%レイテンシが改善している</a>のを眺めており、ちゃんと有意差の出るJITになっているなと感心している。このくらいの差が本番で出てなかった時にその原因を調査したり、対応策をObject Shapeやってる人たちに提案したり、このグラフやそれ以外のメトリクスを持つダッシュボードのメンテとかを僕が担当していた。依然として軸足はコンパイラ開発に置きたいものの、YJITが会社やビジネスにより大きなインパクトを与えられる機会はどんどん活かしていきたい。</p> <h2 id="US生活">US生活</h2> <p>グリーンカードを取り終わった。ビザで生活してるとコロナの影響で再入国できなくなるリスクがあったり、レイオフされたときに面倒だったりするので、取り終えられてよかった。</p> <p>資産運用は2020年末にやっとまともにやり始めたという感じで、2021年は好調、その利益が2022年でひっくり返るみたいな年だったが、まあ多くの人がそうならざるを得ない年だったのではないだろうか。去年市場の調子がよかったころ<a href="https://twitter.com/k0kubun/status/1411140330175361031">2億円</a>を2022年の目標にしてたのが、まあ全然そういう雰囲気じゃなくなったが、資産の大部分を運用に回した状態で不況を経験した結果、長期運用的にはどうにかなりそうだなという実感が得られている。</p> <p>運用視点での今年の面白ポイントとしては、I Bonds (インフレ連動の国債) が金利9.62%保証だった奴を買える枠いっぱい買えたのと、使わなくなってクローズされてたSavings口座を別の銀行で開設したら金利4.11%まで来たところか。もちろん本当に金利に興味がある人はSavings口座ではなくCash Depositとかを使う気がしているが、僕はメインの運用は株と債券でやっているので、ちょっと高い買い物をする前に即出せる場所にお金をプールしておく場所としてSavings口座を使っているに過ぎない。具体的には、来年現金が貯まってきたら車を買い替えようかなという機運になっている。</p> <p>我が家ではプリスクール(幼稚園)は子供が3歳になってから入れようと考えていて、それがとうとう来年まで迫っているので、今年学区とかも全く知識がなかった状態から結構いろいろ調べた。元同僚がプリスクールに月$2000使っているという話を聞いた時はビビっていたが、うちは少なくとも最初は週2~3で午前だけとかがいいねという話をしていて、それだと月$300~400くらいの感じでいけそうな雰囲気。子供が楽しんでくれるといいなと思っている。</p> <h2 id="発表">発表</h2> <p>子供の面倒を妻一人で見るのは大変なので、物理的に参加しないといけないカンファレンスは基本的に敬遠している。例外的に、(会社費用で飛行機代が出る)僕と一緒に家族の分は自費で一時帰国すると妻が実家に帰ることができるRubyKaigiだけはありがたく参加させていただいている。</p> <p>コロナの影響で、オンラインのイベントは今でもそこそこ行なわれていて、ありがたいことにいくつか登壇のお誘いもいただき、以下のイベントで登壇した。</p> <ul> <li><a href="https://rubykaigi.org/2022/">RubyKaigi 2022</a>: <a href="https://speakerdeck.com/k0kubun/rubykaigi-2022">Towards Ruby 4 JIT / RubyKaigi 2022 - Speaker Deck</a><a href="https://b.hatena.ne.jp/entry/https://speakerdeck.com/k0kubun/rubykaigi-2022" class="http-bookmark"><img src="https://b.hatena.ne.jp/entry/image/https://speakerdeck.com/k0kubun/rubykaigi-2022" alt="" class="http-bookmark" /></a></li> <li><a href="https://rust.tokyo/">Rust.Tokyo 2022</a>: <a href="https://speakerdeck.com/k0kubun/rust-dot-tokyo-2022">YJIT: Dive into Ruby&#39;s JIT compiler written in Rust / Rust.Tokyo 2022 - Speaker Deck</a><a href="https://b.hatena.ne.jp/entry/https://speakerdeck.com/k0kubun/rust-dot-tokyo-2022" class="http-bookmark"><img src="https://b.hatena.ne.jp/entry/image/https://speakerdeck.com/k0kubun/rust-dot-tokyo-2022" alt="" class="http-bookmark" /></a></li> <li><a href="https://www.sakurajima-house.tech/">サクラジマハウス 2022</a>: パネルディスカッション (録画なし)</li> <li><a href="https://findy.connpass.com/event/263814/">Findyさんのキャリア戦略イベント</a>: パネルディスカッション (<a href="https://www.youtube.com/watch?v=-vPHYJ34UHA">アーカイブ動画</a>)</li> </ul> <p>例年通りRubyのJITの話をしたのが2回。RubyのJIT開発が業務になった関係で、それをやっている英語話者の同僚にコンテキストを伝える関係上、日本語と英語どちらもサポートしているカンファレンスでは英語でRubyのJITの話をするように意識し始めた。また、Ruby RoguesというPodcastも再びお誘いをいただいて、そこでも英語でRubyのJITの話をしている: <a href="https://topenddevs.com/podcasts/ruby-rogues/episodes/mjit-yjit-and-haml-with-takashi-kokubun-ruby-573">MJIT, YJIT, and HAML - RUBY 573</a>。</p> <p>自分が資料を用意するでもなく、(打ち合わせやネタのメモの用意などは事前にするが)当日他のパネリストに話を振られて応答するスタイルの登壇をしたのは今年が始めてだった。ある程度の頻度で登壇活動をしたい気持ちはあるが、どんなイベントが登壇者を募集してるかの情報を見逃しがちなので、お誘いをいただけるのは助かるしありがたい。</p> <h2 id="ブログ">ブログ</h2> <p><a href="https://blog.hatenablog.com/entry/2022/12/26/180000">2022年「年間総合はてなブログランキング」トップ100</a> に2つランクインしたので、ちょっとがんばった感じがする。一方で今年も1000ブクマに届いてないので、それだけ伸ばせる人たちはすごいなあという気持ちがある。今年書いた記事をブクマ順に並べると以下のような感じになる。</p> <ul> <li><a href="https://k0kubun.hatenablog.com/entry/graduation">&#x50CD;&#x304D;&#x306A;&#x304C;&#x3089;&#x30A2;&#x30E1;&#x30EA;&#x30AB;&#x306E;&#x5927;&#x5B66;&#x9662;&#x3067;CS&#x4FEE;&#x58EB;&#x53F7;&#x3092;&#x53D6;&#x3063;&#x305F; - k0kubun&#39;s blog</a><a href="https://b.hatena.ne.jp/entry/https://k0kubun.hatenablog.com/entry/graduation" class="http-bookmark"><img src="https://b.hatena.ne.jp/entry/image/https://k0kubun.hatenablog.com/entry/graduation" alt="" class="http-bookmark" /></a></li> <li><a href="https://k0kubun.hatenablog.com/entry/surplus">&#x500B;&#x4EBA;&#x958B;&#x767A;&#x3092;&#x9ED2;&#x5B57;&#x306B;&#x3059;&#x308B;&#x6280;&#x8853; - k0kubun&#39;s blog</a><a href="https://b.hatena.ne.jp/entry/https://k0kubun.hatenablog.com/entry/surplus" class="http-bookmark"><img src="https://b.hatena.ne.jp/entry/image/https://k0kubun.hatenablog.com/entry/surplus" alt="" class="http-bookmark" /></a></li> <li><a href="https://k0kubun.hatenablog.com/entry/farewell-treasure-data">Treasure Data &#x3092;&#x9000;&#x8077;&#x3057;&#x307E;&#x3057;&#x305F; - k0kubun&#39;s blog</a><a href="https://b.hatena.ne.jp/entry/https://k0kubun.hatenablog.com/entry/farewell-treasure-data" class="http-bookmark"><img src="https://b.hatena.ne.jp/entry/image/https://k0kubun.hatenablog.com/entry/farewell-treasure-data" alt="" class="http-bookmark" /></a></li> <li><a href="https://k0kubun.hatenablog.com/entry/oss-career">&#x30D5;&#x30EB;&#x30BF;&#x30A4;&#x30E0;OSS&#x30B3;&#x30DF;&#x30C3;&#x30BF;&#x3092;&#x59CB;&#x3081;&#x3066;2&#x304B;&#x6708;&#x7D4C;&#x3063;&#x305F; - k0kubun&#39;s blog</a><a href="https://b.hatena.ne.jp/entry/https://k0kubun.hatenablog.com/entry/oss-career" class="http-bookmark"><img src="https://b.hatena.ne.jp/entry/image/https://k0kubun.hatenablog.com/entry/oss-career" alt="" class="http-bookmark" /></a></li> <li><a href="https://k0kubun.hatenablog.com/entry/neovim-lsp">Neovim&#x3092;&#x4E00;&#x77AC;&#x3067;VSCode&#x4E26;&#x307F;&#x306B;&#x4FBF;&#x5229;&#x306B;&#x3059;&#x308B; - k0kubun&#39;s blog</a><a href="https://b.hatena.ne.jp/entry/https://k0kubun.hatenablog.com/entry/neovim-lsp" class="http-bookmark"><img src="https://b.hatena.ne.jp/entry/image/https://k0kubun.hatenablog.com/entry/neovim-lsp" alt="" class="http-bookmark" /></a></li> <li><a href="https://k0kubun.hatenablog.com/entry/productivity">&#x5F8C;&#x6094;&#x3057;&#x3066;&#x3044;&#x308B;&#x304C;&#x3084;&#x3081;&#x3089;&#x308C;&#x306A;&#x3044;&#x958B;&#x767A;&#x52B9;&#x7387;&#x5411;&#x4E0A;&#x8853; - k0kubun&#39;s blog</a><a href="https://b.hatena.ne.jp/entry/https://k0kubun.hatenablog.com/entry/productivity" class="http-bookmark"><img src="https://b.hatena.ne.jp/entry/image/https://k0kubun.hatenablog.com/entry/productivity" alt="" class="http-bookmark" /></a></li> <li><a href="https://qiita.com/k0kubun/items/4600e52a1a245495dfaa">Ruby 3.2 &#x306E;IRB&#x306E;&#x65B0;&#x6A5F;&#x80FD; #Ruby - Qiita</a><a href="https://b.hatena.ne.jp/entry/https://qiita.com/k0kubun/items/4600e52a1a245495dfaa" class="http-bookmark"><img src="https://b.hatena.ne.jp/entry/image/https://qiita.com/k0kubun/items/4600e52a1a245495dfaa" alt="" class="http-bookmark" /></a></li> <li><a href="https://k0kubun.hatenablog.com/entry/zig">Zig&#x3067;&#x7C21;&#x5358;&#x30AF;&#x30ED;&#x30B9;&#x30B3;&#x30F3;&#x30D1;&#x30A4;&#x30EB; 2022 - k0kubun&#39;s blog</a><a href="https://b.hatena.ne.jp/entry/https://k0kubun.hatenablog.com/entry/zig" class="http-bookmark"><img src="https://b.hatena.ne.jp/entry/image/https://k0kubun.hatenablog.com/entry/zig" alt="" class="http-bookmark" /></a></li> <li><a href="https://qiita.com/k0kubun/items/0925afa44da13649a1a0">YJIT&#x3067;&#x4F7F;&#x3063;&#x305F;Rust&#x306E;&#x7701;&#x30E1;&#x30E2;&#x30EA;&#x5316;&#x30C6;&#x30AF;&#x30CB;&#x30C3;&#x30AF; #Ruby - Qiita</a><a href="https://b.hatena.ne.jp/entry/https://qiita.com/k0kubun/items/0925afa44da13649a1a0" class="http-bookmark"><img src="https://b.hatena.ne.jp/entry/image/https://qiita.com/k0kubun/items/0925afa44da13649a1a0" alt="" class="http-bookmark" /></a></li> </ul> <p>引き続き、登壇の場で放出できなかった面白ネタなどを記事にしていきたい。</p> <h2 id="OSS活動">OSS活動</h2> <p>フルタイムOSS開発者になったが、入社するまではYJITはほとんど触ってなかったので、趣味の時間でやっているOSS活動は入社の前後でそれほど変わっていない。YJIT以外のOSS開発は全てGitHub Sponsorsに支えられている。</p> <h3 id="sqldef-xremap-rspec-openapi">sqldef, xremap, rspec-openapi</h3> <p>僕が作者のOSSの中だと、<a href="https://github.com/k0kubun/sqldef">sqldef</a>と<a href="https://github.com/k0kubun/xremap">xremap</a>の2つに勢いがあり、これを伸ばしたいという気持ちが年の始めくらいからあった。どちらもユーザー数が増えている感覚があり、ありがたいが、どちらのプロジェクトも自分が直接使わない環境もサポートしないといけない難しさを感じている。sqldefの方はSQL Serverサポートメンテナの<a href="https://github.com/ytakaya">@ytakaya</a>さんと、新しくSQLite3サポートメンテナになった<a href="https://github.com/knaka">@knaka</a>さんに非常に助けられている。xremapの方はUbuntuでもX11でもない環境の問題は結構面倒なので、Ubuntu以外のdistroやWaylandを使っているメンテナが可能なら欲しい状況なのだが、今のところそのあてはない。</p> <p>メンテナ移譲関連の話をすると、<a href="https://github.com/exoego/rspec-openapi">rspec-openapi</a>は主に前職で使っていたgemなので、前職にいる間にco-maintainerになっていただいていた<a href="https://github.com/exoego/rspec-openapi">@exoego</a>さんにownershipを移譲させていただいた。精力的にメンテしていただいていて、とてもありがたい。</p> <h3 id="Haml-Temple-Slim">Haml, Temple, Slim</h3> <p>あとはHamlの開発版ブランチをHamlitにリプレースするプロジェクトをマージした後、Haml 6が出ないまま1年が経っていたので、作者をつついてgem pushの権限をもらいHaml 6をリリースし、そこからのリリースやバグ修正は今のところ僕が全部やっている。</p> <p>HamlやHamlitが使っているフレームワークのtempleに関しても、GitHubのwrite権限がある状態だったところからgem pushの権限ももらい、長い間溜まっていた変更をリリースしたりした。そこで出た変更にSlimを追従させる必要性から、(temple対応だけ担当の)Slimのメンテナにもなった。ERBとHamlとSlimの全てのメンテナをやっている人間になった。</p> <h3 id="MJIT">MJIT</h3> <p>業務時間外にYJITに触ってしまうと、成果を出すために実質の残業に依存する習慣がつきかねないため、趣味ではYJITには触らないようにしている。が、それはそれとして結局趣味でもRubyを速くするコンパイラを書くことに一番関心があるため、MJITを触っている。MJITのアーキテクチャでRubyを速くするのは大変なので、デザインそのものをひたすら変え続けていて、Ruby 3.3でもそのあたりをもうちょっと変えてからいろいろやっていく所存。</p> <h2 id="2023年は">2023年は</h2> <p>railsbenchが<a href="https://speed.yjit.org/">1.4倍速くなる</a>現状のYJITもなかなかすごいが、ローカル変数のレジスタ割り当てがまだ終わってないみたいな無限の伸びしろがある状態なので、Ruby 3.3ではモダンな言語処理系に入っている最適化がCRubyのJITに一通り入れられた状態でリリースできるといいなと思う。</p> <p>MJITを一人で開発していた時と違って、YJITでは信頼できる何人ものチームメンバーと一緒に戦えるので、良いものにできそう。</p> k0kubun フルタイムOSSコミッタを始めて2か月経った hatenablog://entry/4207112889922843484 2022-09-29T07:43:08+09:00 2022-09-29T09:02:04+09:00 Shopifyに入社してRubyのJITコンパイラを書く仕事を始めてから2か月経った。 前職の退職エントリ では今後やりたいことを書いたりしたが、実際OSS開発を仕事にしてみてどうだったかみたいなことを書いておく。 シリコンバレーでのリモート生活 3年前に妻とアメリカに移住し、今年永住権も取得した。 Shopifyは本社はカナダにあるし2020年5月からフルリモート企業なのだが、 前職の本社があったシリコンバレーのあたりからそのまま引っ越さずに暮らしている。 なぜシリコンバレーに住み続けるのか フルリモートである以上はカナダ移住のためのビザのサポートを会社がする動機もないため、 現職においても… <p>Shopifyに入社して<a class="keyword" href="http://d.hatena.ne.jp/keyword/Ruby">Ruby</a>の<a class="keyword" href="http://d.hatena.ne.jp/keyword/JIT">JIT</a><a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%B3%A5%F3%A5%D1%A5%A4%A5%E9">コンパイラ</a>を書く仕事を始めてから2か月経った。 前職の<a href="https://k0kubun.hatenablog.com/entry/farewell-treasure-data">退職エントリ</a> では今後やりたいことを書いたりしたが、実際<a class="keyword" href="http://d.hatena.ne.jp/keyword/OSS">OSS</a>開発を仕事にしてみてどうだったかみたいなことを書いておく。</p> <h1 id="シリコンバレーでのリモート生活"><a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%B7%A5%EA%A5%B3%A5%F3%A5%D0%A5%EC%A1%BC">シリコンバレー</a>でのリモート生活</h1> <p>3年前に妻と<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%A2%A5%E1%A5%EA">アメリ</a>カに移住し、今年永住権も取得した。 Shopifyは本社はカナダにあるし2020年5月からフルリモート企業なのだが、 前職の本社があった<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%B7%A5%EA%A5%B3%A5%F3%A5%D0%A5%EC%A1%BC">シリコンバレー</a>のあたりからそのまま引っ越さずに暮らしている。</p> <h2 id="なぜシリコンバレーに住み続けるのか">なぜ<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%B7%A5%EA%A5%B3%A5%F3%A5%D0%A5%EC%A1%BC">シリコンバレー</a>に住み続けるのか</h2> <p>フルリモートである以上はカナダ移住のためのビザのサポートを会社がする動機もないため、 現職においても住む国の選択肢は基本的に日本か<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%A2%A5%E1%A5%EA">アメリ</a>カになると思っている。</p> <p>飯が安くて美味いのを主な理由として妻も僕も住むなら<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%A2%A5%E1%A5%EA">アメリ</a>カより日本の方が好きなのだが、 住む地域ベースで多くの企業が給料に傾斜をかけてくることを理由に<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%B7%A5%EA%A5%B3%A5%F3%A5%D0%A5%EC%A1%BC">シリコンバレー</a>に住み続けている。</p> <p>東京だと、現地の企業では良くて年収1000万円、金払いのいい<a class="keyword" href="http://d.hatena.ne.jp/keyword/%B3%B0%BB%F1">外資</a>に行くと2000万円という感じだと思うが、 <a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%B7%A5%EA%A5%B3%A5%F3%A5%D0%A5%EC%A1%BC">シリコンバレー</a>に住んでいれば、スタートアップでも $180,000 (2600万円) あたりが割とよくある感じだし、 上場してる大きめの企業だと、結構多くの人が $360,000 (5200万円) くらいのTotal Compのオファーをもらってそうな雰囲気を <a class="keyword" href="http://d.hatena.ne.jp/keyword/YouTube">YouTube</a>やlevels.fyiから感じる。</p> <h2 id="リモートペアプログラミング文化">リモート<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%DA%A5%A2%A5%D7%A5%ED%A5%B0%A5%E9%A5%DF%A5%F3%A5%B0">ペアプログラミング</a>文化</h2> <p>前職では様々な人と定期的に1on1をすることでリモートでのコミュニケーションを活発に行なっていた。 Slackより1on1の方が深い関係を築きやすいので、特に転職したばかりの新人の自分はそれを積極的にやっていく必要があると考えたが、 現職では、マネージャー以外と定期的な1on1をしてる人が少なそうに見えた。</p> <p>一方、Shopifyは全社的に<a href="https://tuple.app/">Tuple</a>という<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%DA%A5%A2%A5%D7%A5%ED">ペアプロ</a>サービスを導入していて、定期的な<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%DA%A5%A2%A5%D7%A5%ED">ペアプロ</a>ミーティングを毎週複数持っているみたいな人は逆に多そうだった。同じ仕事をしてるチームメンバーとは<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%DA%A5%A2%A5%D7%A5%ED">ペアプロ</a>をし、それ以外の人たちとは突発的な1on1を申し込むという感じで関係性を築いていくことになろうかと思っている。</p> <h2 id="北米東海岸と日本の時差">北米<a class="keyword" href="http://d.hatena.ne.jp/keyword/%C5%EC%B3%A4%B4%DF">東海岸</a>と日本の時差</h2> <p>前職は<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%A2%A5%E1%A5%EA">アメリ</a>カ在住の社員は基本西海岸にいるという感じだったが、 現職では<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%A2%A5%E1%A5%EA">アメリ</a>カでもカナダでも<a class="keyword" href="http://d.hatena.ne.jp/keyword/%C5%EC%B3%A4%B4%DF">東海岸</a>の<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%BF%A5%A4%A5%E0%A5%BE%A1%BC%A5%F3">タイムゾーン</a>に住んでる人がかなり多いことに違いを感じている。</p> <p>日本と西海岸でミーティングをする場合、双方の働いてる時間が被る1~2時間を使うとまともな時間にそれを行なえるが、 日本と東海外だと時差が13時間あり、両者が業務時間内になるタイミングでミーティングをするのが不可能という感じになっている。</p> <p>普段は西海岸に住んでるので問題ないのだが、カンファレンスで日本に出張したついでに日本に滞在して一時的にそこから働くということをすると、ミーティングが必要な仕事は全て<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%A2%A5%E1%A5%EA">アメリ</a>カに帰るまで先延しみたいな感じになる。僕は業務時間外にミーティングをしたくないし相手にも強要したくないので、現状特に解決方法がない感じになっている。</p> <h1 id="OSS開発とビジネスインパクト"><a class="keyword" href="http://d.hatena.ne.jp/keyword/OSS">OSS</a>開発とビジネス<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%A4%A5%F3%A5%D1%A5%AF">インパク</a>ト</h1> <h2 id="コンパイラエンジニアというキャリア"><a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%B3%A5%F3%A5%D1%A5%A4%A5%E9">コンパイラ</a>エンジニアというキャリア</h2> <p>今回の転職で、分散システムの開発というかなり求人の多い職種から、 言語処理系の最適化というニッチな分野にキャリ<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%A2%A5%C1%A5%A7">アチェ</a>ンジした。 <a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%B3%A5%F3%A5%D1%A5%A4%A5%E9">コンパイラ</a>を商品として提供している会社ならまだしも、 特にそういうわけでもない会社で、誰でも無料で使える言語処理系の最適化を仕事にするというのは、 会社に予算を充ててもらうハードルが高そうなイメージがある。</p> <p>言語処理系開発というキャリアについて考えるとき、 <a href="https://medium.com/@katelyngadd/why-i-quit-googles-webassembly-team-and-how-it-made-me-sick-c50ef562ce1">GoogleでWebAssemblyを開発していたが病んでしまった人</a> のことをよく思い出すのだが、 なかなか経営陣に人や予算を割り当ててもらいにくそうな仕事に就いている という点に関しては常に意識しておく必要があると思っている。</p> <h2 id="基盤開発と利益部門の関係">基盤開発と利益部門の関係</h2> <p>その一方で、過度に悲観的になる必要もないと最近は考えている。 というのも、どれだけ<a class="keyword" href="http://d.hatena.ne.jp/keyword/OSS">OSS</a>を活用してプロダクト開発に集中しようとしている組織でも、 自分たちの特殊なニーズに合わせて基盤技術の改善を行なうことで開発や運用が効率的にできるようになる状況はいくらでもあるし、 特に大きな組織ではその価値がスケールしやすい。 僕は<a class="keyword" href="http://d.hatena.ne.jp/keyword/Ruby">Ruby</a>や<a class="keyword" href="http://d.hatena.ne.jp/keyword/Rails">Rails</a>の<a class="keyword" href="http://d.hatena.ne.jp/keyword/OSS">OSS</a>開発を主に行なうグループに所属していて、大体40人くらいいるのだが、 社員が9000人ほどいる会社ではそこに投資しすぎということにもならないのだろう。</p> <p>現職の例だと、<a class="keyword" href="http://d.hatena.ne.jp/keyword/Ruby">Ruby</a>を使ってプロダクトの開発と運用を行なっていく上で <a class="keyword" href="http://d.hatena.ne.jp/keyword/JIT">JIT</a>や<a class="keyword" href="http://d.hatena.ne.jp/keyword/GC">GC</a>の改善によって速度改善が得られればユーザー体験が向上するし、 メモリ使用量が減れば台数が減らせてコスト削減にもなる。 全社的にサーバーサイドに<a class="keyword" href="http://d.hatena.ne.jp/keyword/Ruby">Ruby</a>を使っていて、サーバーの数も社員の数も多いため、 この基盤の改善が会社に与える<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%A4%A5%F3%A5%D1%A5%AF">インパク</a>トは並の企業より大きいことになる。 そうすると、利益部門が出した売上の一部を基盤開発に充てる経営妥当性も十分説明できそうな感じがする。 特にShopifyの場合はCEOが元<a class="keyword" href="http://d.hatena.ne.jp/keyword/Rails">Rails</a>コミッタなので、そこを誰かが説明してあげる必要もないという強みもある。</p> <h2 id="仕事の評価と待遇">仕事の評価と待遇</h2> <p><a class="keyword" href="http://d.hatena.ne.jp/keyword/Ruby">Ruby</a>や<a class="keyword" href="http://d.hatena.ne.jp/keyword/Rails">Rails</a>自体のフルタイム開発を仕事にしている他の日本人と話すと、 Shopifyみたいに開発目標を立ててチームで<a class="keyword" href="http://d.hatena.ne.jp/keyword/OSS">OSS</a>開発をして<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%A4%A5%F3%A5%D1%A5%AF">インパク</a>トレビューもして給料に反映させますみたいな環境より、 待遇がある程度犠牲になっても何でも自由に開発していいみたいな会社の方が好き、 という意見を聞くことが複数あった。</p> <p>僕もお金を稼ぐ目的は経済的に自由になって選択肢を増やすことなので、 そもそも仕事も自由にしたいという気持ちには一定の共感があるが、 自分がやりたい仕事を取ってきたり自分の仕事を適切に評価してもらうためにコミュニケーションしたりすることに慣れたので、 そこにはそれほど抵抗を感じないようになった。 むしろ、成果を出したらそれが待遇にも反映されることで得られる満足感もあると思うが、 そこが実際どうかは実際のレビューを経てみないと何とも言えなそう。</p> <h2 id="カンファレンス登壇業務">カンファレンス登壇業務</h2> <p>僕のグループではカンファレンス登壇が主要な業務の一つという風にマネージャーも認識していて、 RubyKaigiの<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%C8%A1%BC%A5%AF">トーク</a>の準備をするので他の仕事が1週間全く進捗しませんみたいな状態でも誰も文句を言わない雰囲気がある。 登壇1回するごとにちょっとボーナスももらえるのでお得。</p> <p>自分たちが作る基盤を<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%D7%A5%ED%A5%D7%A5%E9%A5%A4%A5%A8%A5%BF%A5%EA">プロプライエタリ</a>ではなくオープンにやるのは、 それによってより多くの環境でテストされたり、社外からもコントリビューションが来たりすることで品質が上がるなどのメリットがあるからだと思うが、 実際にそれが起こるようにして自分たちの仕事の<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%A4%A5%F3%A5%D1%A5%AF">インパク</a>トを大きくしていく上でカンファレンス登壇は実際に必要な業務だと感じる。</p> <h1 id="キャリアチェンジの感想">キャリ<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%A2%A5%C1%A5%A7">アチェ</a>ンジの感想</h1> <p>前職では自分の書いたコードが直接売上に貢献しうる仕事をしていたので、 <a class="keyword" href="http://d.hatena.ne.jp/keyword/OSS">OSS</a>開発なんか仕事にして大丈夫かという不安も以前はあったが、 実際に入社してみると、自分が今最も技術的に興味のある課題に取り組めることがとても楽しく感じる。</p> <p><a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%B7%A5%EA%A5%B3%A5%F3%A5%D0%A5%EC%A1%BC">シリコンバレー</a>に住んでれば面白くて待遇の良い転職先なんていくらでもあるので、 変に先のことを気にして何かを妥協するより、 今一番面白いと思えることができる環境に今後も身を置き続けようと思うようになった。</p> k0kubun Neovimを一瞬でVSCode並みに便利にする hatenablog://entry/4207112889914599410 2022-09-03T20:06:50+09:00 2022-09-05T09:29:55+09:00 去年8年ぶりに vimrc を書き直した時はLSPの体験があんまりよくなくてLSPなしでNeovimを使い続けていたのだが、様々な言語のOSSをメンテする都合で用途に応じてIntelliJとVSCodeとNeovimの三刀流で暮らしていた結果、可能ならNeovimに寄せたいけどそれならLSPを使いたいなということになり、今回LSPの所を真面目に設定し直して、かなり良い体験になっている。 正直Neovimの設定はVSCodeのそれに比べたら面倒なんじゃないかという印象がありサボっていた節があるが、実際にやってみるとVSCodeと同程度に簡単に済む方法もあったので紹介したい。 何故Neovimなの… <p>去年<a href="https://k0kubun.hatenablog.com/entry/vimrc-2021">8年ぶりに vimrc を書き直した</a>時はLSPの体験があんまりよくなくてLSPなしでNeovimを使い続けていたのだが、様々な言語の<a class="keyword" href="http://d.hatena.ne.jp/keyword/OSS">OSS</a>をメンテする都合で用途に応じて<a class="keyword" href="http://d.hatena.ne.jp/keyword/IntelliJ">IntelliJ</a>と<a class="keyword" href="http://d.hatena.ne.jp/keyword/VSCode">VSCode</a>とNeovimの三刀流で暮らしていた結果、可能ならNeovimに寄せたいけどそれならLSPを使いたいなということになり、今回LSPの所を真面目に設定し直して、かなり良い体験になっている。</p> <p>正直Neovimの設定は<a class="keyword" href="http://d.hatena.ne.jp/keyword/VSCode">VSCode</a>のそれに比べたら面倒なんじゃないかという印象がありサボっていた節があるが、実際にやってみると<a class="keyword" href="http://d.hatena.ne.jp/keyword/VSCode">VSCode</a>と同程度に簡単に済む方法もあったので紹介したい。</p> <h1 id="何故Neovimなのか">何故Neovimなのか</h1> <p>LSPの話の前に、タイトルだけ見た人がそもそも単に<a class="keyword" href="http://d.hatena.ne.jp/keyword/VSCode">VSCode</a>使えばいいじゃんと言いそうなので、どうして<a class="keyword" href="http://d.hatena.ne.jp/keyword/IntelliJ">IntelliJ</a>や<a class="keyword" href="http://d.hatena.ne.jp/keyword/VSCode">VSCode</a>ではなくNeovimに揃えようと思ったのかについて書いておく。</p> <h2 id="IntelliJの不便なところ"><a class="keyword" href="http://d.hatena.ne.jp/keyword/IntelliJ">IntelliJ</a>の不便なところ</h2> <p>JetBrainsの<a class="keyword" href="http://d.hatena.ne.jp/keyword/IDE">IDE</a>には<a class="keyword" href="http://d.hatena.ne.jp/keyword/Ruby">Ruby</a>とCを両方正式にサポートしている<a class="keyword" href="http://d.hatena.ne.jp/keyword/IDE">IDE</a>がなく <a href="#f-1d85b5f6" name="fn-1d85b5f6" title="https://www.jetbrains.com/help/idea/discover-intellij-idea.html に &quot;C/C++ are not officially supported in IntelliJ IDEA, but you can use CLion&quot; と書いてある">*1</a> 、CRuby開発者的には大変不便である。やるならRubyMineとCLionをいったり来たりしないといけないが、<a href="https://k0kubun.hatenablog.com/entry/productivity">C-なんとかでウィンドウ切り替え</a>をしている都合、エディタに2つもショートカットを使うのは正直勘弁願いたいという状態である。仮にショートカットの問題がなかったとしても、一窓で完結できる<a class="keyword" href="http://d.hatena.ne.jp/keyword/VSCode">VSCode</a>やNeovimに比べて体験が劣るのは変わらないと思う。</p> <p>それがモチベーションで<a class="keyword" href="http://d.hatena.ne.jp/keyword/VSCode">VSCode</a>を使い始めたのだが、Kotlinや<a class="keyword" href="http://d.hatena.ne.jp/keyword/Ruby">Ruby</a>は<a class="keyword" href="http://d.hatena.ne.jp/keyword/IntelliJ">IntelliJ</a>やRubyMineの方が<a class="keyword" href="http://d.hatena.ne.jp/keyword/VSCode">VSCode</a>より圧倒的に言語サポートが充実している <a href="#f-754381c4" name="fn-754381c4" title="Kotlinに関しては同じ会社が作っている以上は、JetBrainsが作っているIDEが一番充実しているという状態は揺るがないと思う">*2</a> ので、できれば<a class="keyword" href="http://d.hatena.ne.jp/keyword/IntelliJ">IntelliJ</a>にCをサポートしてもらうのが一番望ましいのだが、そうなりそうな見込みはない。</p> <p>次に困るのが、<a class="keyword" href="http://d.hatena.ne.jp/keyword/Vim">Vim</a>のタブに相当するものがないこと。<a class="keyword" href="http://d.hatena.ne.jp/keyword/Vim">Vim</a>はタブの中で画面を分割し、分割された窓の中で更に複数バッファを持つという感じなのだが、<a class="keyword" href="http://d.hatena.ne.jp/keyword/IntelliJ">IntelliJ</a>ではトッ<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%D7%A5%EC%A5%D9">プレベ</a>ルで画面を分割し、その中で複数バッファを持つという感じなので、<a class="keyword" href="http://d.hatena.ne.jp/keyword/Vim">Vim</a>のバッファのようなものはあるが<a class="keyword" href="http://d.hatena.ne.jp/keyword/Vim">Vim</a>のタブはないという感じになっている。<a class="keyword" href="http://d.hatena.ne.jp/keyword/Vim">Vim</a>のタブは同じファイルの別の場所のコンテキストを保存しながら作業するといった用途に便利で、これがないのは大変辛いのだが、まあこれも<a class="keyword" href="http://d.hatena.ne.jp/keyword/IntelliJ">IntelliJ</a>に入ることはないだろう。</p> <p><a class="keyword" href="http://d.hatena.ne.jp/keyword/Vim">Vim</a><a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%AD%A1%BC%A5%D0%A5%A4%A5%F3%A5%C9">キーバインド</a>ユーザー的にはIdeaVimの挙動の<a class="keyword" href="http://d.hatena.ne.jp/keyword/Vim">Vim</a>互換性がイマイチなのも気になるところだが、VSCodeVimや<a class="keyword" href="http://d.hatena.ne.jp/keyword/VSCode">VSCode</a> Neovimがあまりにも厳しいので、最近はIdeaVimの方がマシだなという評価になってきた。そもそも<a class="keyword" href="http://d.hatena.ne.jp/keyword/Vim">Vim</a>やNeovimを使ってしまった方が早いというのはそう。</p> <h2 id="VSCodeの不便なところ"><a class="keyword" href="http://d.hatena.ne.jp/keyword/VSCode">VSCode</a>の不便なところ</h2> <p>Kotlinを書く会社をやめて<a class="keyword" href="http://d.hatena.ne.jp/keyword/Ruby">Ruby</a>とCを同時にいじるCRuby開発をする会社に入社したので、仕事で使う<a class="keyword" href="http://d.hatena.ne.jp/keyword/IDE">IDE</a>が<a class="keyword" href="http://d.hatena.ne.jp/keyword/IntelliJ">IntelliJ</a>から<a class="keyword" href="http://d.hatena.ne.jp/keyword/VSCode">VSCode</a>にシフトしたのはごく自然なことなのだが、個人的にはJetBrainsの<a class="keyword" href="http://d.hatena.ne.jp/keyword/IDE">IDE</a>の方が<a class="keyword" href="http://d.hatena.ne.jp/keyword/VSCode">VSCode</a>より便利だなあと思うシーンの方が多いので、<a class="keyword" href="http://d.hatena.ne.jp/keyword/VSCode">VSCode</a>が業界で一番人気ぽい雰囲気なのは個人的にはやや意外である。</p> <p><a class="keyword" href="http://d.hatena.ne.jp/keyword/VSCode">VSCode</a>で一番困っているのは、エディタで改行した時の自動インデントの開始位置がかなり異常なことで、VSCodeVimはデフォルトの<a class="keyword" href="http://d.hatena.ne.jp/keyword/VSCode">VSCode</a>のインデント挙動に従うのでこの不便をもろに受けてしまう。具体的には、以下のように空行にカーソルがある時、</p> <pre class="code lang-ruby" data-lang="ruby" data-unlink><span class="synPreProc">def</span> <span class="synIdentifier">foo</span> bar [ここ] baz <span class="synPreProc">end</span> </pre> <p>僕は空行にはスペースを残さない派なのでインデントがないところに静止するが、そこから改行すると次の行でもインデントなしで始まってしまう。ここではbazと同じインデント位置から次の行を始めたいわけだが、そうならない。他にも気になる挙動がかなりいっぱいある。そこで便利なのが<a class="keyword" href="http://d.hatena.ne.jp/keyword/VSCode">VSCode</a> Neovimという<a class="keyword" href="http://d.hatena.ne.jp/keyword/VSCode">VSCode</a>をNeovimフロントエンドとして使う<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%D7%A5%E9%A5%B0%A5%A4%A5%F3">プラグイン</a>なのだが、これを使うと度々Neovimと<a class="keyword" href="http://d.hatena.ne.jp/keyword/VSCode">VSCode</a>の同期が壊れたっぽくなって不便というのはおいておいて、VSCodeVimで存在するインデントの問題は解消するものの、それとは全然違うところでNeovimとは異なる不思議なインデントの挙動をする。何故Neovimと同じ挙動をしてくれないのかよくわからないが、これが理由で<a class="keyword" href="http://d.hatena.ne.jp/keyword/VSCode">VSCode</a>を使うのが辛くなってしまった。</p> <p><a class="keyword" href="http://d.hatena.ne.jp/keyword/IntelliJ">IntelliJ</a>のところに書いた<a class="keyword" href="http://d.hatena.ne.jp/keyword/Vim">Vim</a>のタブに相当するものがない問題は<a class="keyword" href="http://d.hatena.ne.jp/keyword/VSCode">VSCode</a>にも同様に存在する。これが<a class="keyword" href="http://d.hatena.ne.jp/keyword/VSCode">VSCode</a>の辛さに拍車をかけている。<a class="keyword" href="http://d.hatena.ne.jp/keyword/VSCode">VSCode</a>ではこれは<a href="https://github.com/microsoft/vscode/issues/41289">やらないと明確に宣言されている</a>ので、絶望である。</p> <h2 id="Neovimの不便なところ">Neovimの不便なところ</h2> <p>この中では一番便利だと思っているが、公平性のためにも(?)、自分がNeovimに感じている不満についても書いておこうと思う。</p> <p>僕はNeovimの利点の一つがターミナル上で起動してtmuxのウィンドウの1つにしたりできることだと思っていて、<a class="keyword" href="http://d.hatena.ne.jp/keyword/CUI">CUI</a><a class="keyword" href="http://d.hatena.ne.jp/keyword/%A4%AB%A4%E9%A4%B7">からし</a>か起動しないのだが、そのためターミナルが表現できるUIしか使えないという欠点がある。これまでそれほど気になることはなかったが、LSPのdiagnosticsでエラーが出るところに赤い波線ではなく文字と同じ下線しかいれられないとか、これくらいはそんなに頻繁に使わないからショートカットで効率化するんじゃなくてマウスで操作してもいいんだけどなみたいのがそもそも選択肢として存在しなくて、僕が乱暴に消費しまくっているショートカットキーと衝突している機能を使う必要が出てくる。とはいえ、いずれも大した問題ではない。</p> <h1 id="Neovimの二大LSPプラグイン">Neovimの二大LSP<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%D7%A5%E9%A5%B0%A5%A4%A5%F3">プラグイン</a></h1> <p>やっとLSPの話。<a class="keyword" href="http://d.hatena.ne.jp/keyword/vim">vim</a>-jpを眺めていると、設定の仕方が二大派閥みたいになっていて、僕は両方完全に設定を終えてみた上で片方を選ぶという風にしたので、違いについて書いておく。</p> <h2 id="nvim-lspconfig">nvim-lspconfig</h2> <p>そもそもNeovimにはビルトインのLSPクライアント nvim-lsp があるのだが、<a href="https://github.com/neovim/nvim-lspconfig">nvim-lspconfig</a>はそれの設定だけ提供するというもの。大雑把に言うと以下のような特徴がある。</p> <ul> <li>nvim-lspconfigがサポートしているLSPの幅が広い</li> <li>デフォルトの設定がややイケてないので、設定に時間がかかる <ul> <li>デフォルトだとdiagnosticsがインラインで全て展開されるが、情報量多すぎて見にくいので、カーソル合わせたところだけ出すようにしたくなる (設定は可能)</li> <li><a href="https://github.com/j-hui/fidget.nvim">fidget.vim</a> いれたり <a href="https://github.com/nvim-lualine/lualine.nvim">lualine.nvim</a> のカスタマイズなどで自分からprogress出すようにしないと使いにくい (設定は可能)</li> <li>Language Serverのインストールも<a href="https://github.com/williamboman/mason.nvim">mason.nvim</a>とかが必要</li> </ul> </li> </ul> <p>次の奴に比べるとこちらの方がカスタマイズが効いて<a class="keyword" href="http://d.hatena.ne.jp/keyword/Vim">Vim</a>っぽいので、<a class="keyword" href="http://d.hatena.ne.jp/keyword/Vim">Vim</a>過激派(?)の人はこちらを好みそうだなという感じはある。</p> <h2 id="cocnvim">coc.nvim</h2> <p>それとよく対比されるものとして<a href="https://github.com/neoclide/coc.nvim">coc.nvim</a>がある。"Make your <a class="keyword" href="http://d.hatena.ne.jp/keyword/Vim">Vim</a>/Neovim as smart as <a class="keyword" href="http://d.hatena.ne.jp/keyword/VSCode">VSCode</a>" というキャッチコピーなのだが、これは単にLSPを使っているというよりは実際に<a class="keyword" href="http://d.hatena.ne.jp/keyword/VSCode">VSCode</a>の<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%D7%A5%E9%A5%B0%A5%A4%A5%F3">プラグイン</a>を移植して来ることで動いている。そのため<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%D7%A5%E9%A5%B0%A5%A4%A5%F3">プラグイン</a>も<a class="keyword" href="http://d.hatena.ne.jp/keyword/Vim">Vim</a>側ではなくnode.js側のエコシステムで管理することになり、設定も<a class="keyword" href="http://d.hatena.ne.jp/keyword/JSON">JSON</a>に書くところを含め、何かと<a class="keyword" href="http://d.hatena.ne.jp/keyword/Vim">Vim</a>というよりは<a class="keyword" href="http://d.hatena.ne.jp/keyword/VSCode">VSCode</a>ぽい感じの挙動をする。以下のような印象がある。</p> <ul> <li><a class="keyword" href="http://d.hatena.ne.jp/keyword/VSCode">VSCode</a>でメジャーな拡張に相当するものは大体あるが、nvim-lspconfigに比べると少ない</li> <li>あまり設定しなくてもいい感じになる <ul> <li>いい感じのポップアップUIで進捗が出たり、Language Serverのインストールもやってくれたり、最初から<a class="keyword" href="http://d.hatena.ne.jp/keyword/VSCode">VSCode</a>ぽくなっている</li> </ul> </li> </ul> <p>例えばcoc.nvimだと<a class="keyword" href="http://d.hatena.ne.jp/keyword/Ruby">Ruby</a>のLanguage ServerがSolargraphしか対応してないのだが、nvim-lspconfigでいろいろ試した結果Solargraphが一番よくできていると思ったので、正直設定に時間をかける余裕がそれほどないというのもあり、coc.nvimでいいかという感じになった。</p> <p>タイトルの「Neovimを一瞬で<a class="keyword" href="http://d.hatena.ne.jp/keyword/VSCode">VSCode</a>並みに便利にする」というのはどうやるかというと、つまり忙しい人はcoc.nvimを使っておけということである。nvim-lspconfigの方の設定は何行にも渡って設定が必要だったが、coc.nvimの方はインストールしておきたい<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%D7%A5%E9%A5%B0%A5%A4%A5%F3">プラグイン</a>の列挙と<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%AD%A1%BC%A5%D0%A5%A4%A5%F3%A5%C9">キーバインド</a>の設定だけでほぼ使える状況になった。実際にはstatuslineに <code>coc#status()</code> を出したり <a href="https://github.com/petertriho/nvim-scrollbar">nvim-scrollbar</a> でdiagnosticsの分布がパッと分かるようにしてみたりしたが、definitionに飛んだりcompletion出したりするみたいな用途ではデフォルトでほぼ困らない。</p> <p>ちなみにこの記事で主に<a class="keyword" href="http://d.hatena.ne.jp/keyword/Vim">Vim</a>ではなくNeovimの話をしているのは、この<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%D7%A5%E9%A5%B0%A5%A4%A5%F3">プラグイン</a>は<s>Neovimじゃないと動かないからだ</s> (編集: 名前の通り当初はNeovim限定だったものの、今は<a class="keyword" href="http://d.hatena.ne.jp/keyword/Vim">Vim</a>でも動くらしい <a href="#f-0d5f2c01" name="fn-0d5f2c01" title="ycinoさんに教わりました、感謝。一方、最初Neovimにしか対応してなかったことからも、この段落で言ってることは依然としてそれほど外してないように思うので、そのまま残した。">*3</a> )。<a class="keyword" href="http://d.hatena.ne.jp/keyword/Vim">Vim</a> 9は<a class="keyword" href="http://d.hatena.ne.jp/keyword/Vim">Vim</a> 9 Scriptを発明するみたいなことをやってるが、まあ皆<a class="keyword" href="http://d.hatena.ne.jp/keyword/Vim">Vim</a> 9専用言語より<a class="keyword" href="http://d.hatena.ne.jp/keyword/Lua">Lua</a>とかNode.jsとか<a class="keyword" href="http://d.hatena.ne.jp/keyword/Python">Python</a>を書きたくて、長期的にNeovimの方がエコシステムが発達していくんじゃないかと思っている。</p> <h1 id="各言語のLSP">各言語のLSP</h1> <p>まだcoc.nvimを使い始めて日が浅いので、直近使っている数少ない<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%D7%A5%E9%A5%B0%A5%A4%A5%F3">プラグイン</a>についてしか言及しないが、ここで書いてない奴も例えばGoとかはgoplsの奴使って大体<a class="keyword" href="http://d.hatena.ne.jp/keyword/VSCode">VSCode</a>と同じになりそうだなという印象しかないので、<a href="https://github.com/neoclide/coc.nvim/wiki/Using-coc-extensions">Wiki</a>で各言語の<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%D7%A5%E9%A5%B0%A5%A4%A5%F3">プラグイン</a>名を調べてインストールするだけで特に困ることはなさそう。とはいえ、せっかくなので既に使った奴に関しては感想を残しておく。</p> <h2 id="C">C</h2> <p>coc-clangdとcoc-cclsを試したが、どっちも変わらんなと思ったのでclangdをいれるだけで良いcoc-clangdを使っている。CRubyだとclangdがfalse positiveなdiagnosticsをまあまあ出してくるが、それは<a class="keyword" href="http://d.hatena.ne.jp/keyword/VSCode">VSCode</a>デフォルトの<a class="keyword" href="http://d.hatena.ne.jp/keyword/vscode">vscode</a>-cpptoolsでも同じなので、まあ<a class="keyword" href="http://d.hatena.ne.jp/keyword/C%B8%C0%B8%EC">C言語</a>を使っているのが悪いということで諦めている。</p> <p><a class="keyword" href="http://d.hatena.ne.jp/keyword/vscode">vscode</a>-cpptoolsに相当する奴は移植するつもりがcocに移植するつもりが今のところないらしいが、<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%B3%A5%F3%A5%D1%A5%A4%A5%E9">コンパイラ</a>に<a class="keyword" href="http://d.hatena.ne.jp/keyword/gcc">gcc</a>を使っていようがclangを使っていようがclangdの体験は大して変わらないので、coc-clangdでよさそう。むしろ<a class="keyword" href="http://d.hatena.ne.jp/keyword/vscode">vscode</a>-cpptoolsは何か知らないけどエディタ起動するだけで勝手にconfigureとかビルド始めてビルド<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%C7%A5%A3%A5%EC%A5%AF%A5%C8">ディレクト</a>リを壊されるのが気になっていて、clangdに移行して良かったという感じがある。</p> <p>追記: 最初書き忘れてた内容として、Cは<a class="keyword" href="http://d.hatena.ne.jp/keyword/Vim">Vim</a>デフォルトの<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%B7%A5%F3%A5%BF%A5%C3%A5%AF%A5%B9">シンタックス</a>ハイライトが弱いので、coc-settings.<a class="keyword" href="http://d.hatena.ne.jp/keyword/json">json</a> の <code>semanticTokens.filetypes</code> でセマンティック<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%B7%A5%F3%A5%BF%A5%C3%A5%AF%A5%B9">シンタックス</a>ハイライトを有効にすると便利。あとclangdの設定としてcompile_commands.<a class="keyword" href="http://d.hatena.ne.jp/keyword/json">json</a>が必要なんだけど、これは<a href="https://github.com/rizsotto/Bear">bear</a>を使って makeのかわりに bear makeとすると良い。これをやる時は1からビルドする状態でmakeを叩く必要がある。</p> <h2 id="Rust">Rust</h2> <p><a class="keyword" href="http://d.hatena.ne.jp/keyword/VSCode">VSCode</a>と同じでrust-analyzerを使う。おしまい。rust-analyzerは<a class="keyword" href="http://d.hatena.ne.jp/keyword/VSCode">VSCode</a>でもNeovimでもファイルを保存した時に実行されるので、いくつかのdiagnosticsはエディタ上で修正しても保存をもう一度叩くまで警告されっぱなしになったりするのだが、良くも悪くも<a class="keyword" href="http://d.hatena.ne.jp/keyword/VSCode">VSCode</a>とNeovimはこれに関しては似たような体験になる。<a class="keyword" href="http://d.hatena.ne.jp/keyword/IntelliJ">IntelliJ</a>やCLionでは保存しなくてもdiagnosticsが直るような自然な挙動になっていた気がするが、どうもJetBrainsは<a href="https://plugins.jetbrains.com/plugin/8182-rust/docs/rust-faq.html">rust-analyzerは一部のコードを共有しているだけで、Rust対応が基本スクラッチになっている</a>ようで、他の場所では素のrust-analyzerに比べ微妙ぽい挙動をしていた記憶 <a href="#f-d2ce88f0" name="fn-d2ce88f0" title="unused importの警告がないとかだったような気がするけど、うろおぼえ。それは最新版では直ってたりするかも">*4</a> があり、Rustに関してはどのエディタが特別体験が良いとかはなさそう。</p> <h2 id="Ruby"><a class="keyword" href="http://d.hatena.ne.jp/keyword/Ruby">Ruby</a></h2> <p><a class="keyword" href="http://d.hatena.ne.jp/keyword/Ruby">Ruby</a>は自分で型を書く場合は<a href="https://github.com/sorbet/sorbet">Sorbet</a>や<a href="https://github.com/soutaro/steep">Steep</a>を使っておくと、LSPが割といい感じになるらしいのだが、僕は仕事とは別に最近CRubyの標準ライブラリを秘かに書き続けていて、<a class="keyword" href="http://d.hatena.ne.jp/keyword/ruby">ruby</a>/<a class="keyword" href="http://d.hatena.ne.jp/keyword/ruby">ruby</a>のトッ<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%D7%A5%EC%A5%D9">プレベ</a>ルにおもむろにGemfileを置いたりするわけにはいかないので、別途型情報がなくても自明な範囲で定義ジャンプやdiagnosticsがやりたいなという気持ちがあった。</p> <p>SorbetやSteepを使わない場合に関してはRubyMineが圧倒的に体験がよくて、これはLSPでは太刀打ちできない感じがあり、普通の人は基本的にRubyMineを使っておけば良いと思っている。その一方で<a class="keyword" href="http://d.hatena.ne.jp/keyword/Ruby">Ruby</a>とCを両方RubyMineからいじれないという問題があるので、CRuby開発者やC拡張gemメンテナでかつ複数エディタを行ったり来たりしたくない人は、LSPで耐える必要がある。</p> <p>その範囲ではSolargraphが現状一番よくできているというか、定義ジャンプに使うという用途では選択肢が実質これしかない。他のものは <code>textDocument/definition</code> がそもそも提供されてなかったり、それがexperimentalになっていて有効化しても起動時に壊れたり、解析対象がものすごく小さくないと動かなかったりする。SolargraphはSolargraphでまあまあ対応してない<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%B7%A5%F3%A5%BF%A5%C3%A5%AF%A5%B9">シンタックス</a>があって、じゃあと思って<a href="https://github.com/castwide/solargraph/pull/581">PR送っても</a>割とPR来てもマージしてなさそうな雰囲気だったりとか、それができなければSolargraphに忖度したコード (<a href="https://twitter.com/k0kubun/status/1565866796044800000">例</a>) を書くはめになったりとか、<a class="keyword" href="http://d.hatena.ne.jp/keyword/RBS">RBS</a>も未対応だとか、かなり先が長い感じがする。同僚やr7kamuraさんとかがその辺に対応した別のものを開発しそうな気配を感じており、応援している。</p> <p><a class="keyword" href="http://d.hatena.ne.jp/keyword/Ruby">Ruby</a>は自分がコミッターをやっているのもあって<a class="keyword" href="http://d.hatena.ne.jp/keyword/IDE">IDE</a>なくても書けるやろみたいな慢心をしていた節があり、<a class="keyword" href="http://d.hatena.ne.jp/keyword/RBS">RBS</a>で型付けをしたりLSPを使って開発体験向上みたいなのもつい最近までほとんど興味がなかったのだが、実際に使ってみると、今のSolargraphのクオリティのものでもかなり開発効率が上がったように感じる。一方でSorbetやSteep以外のLSPの現状最高の体験がこれかあ、というのは他の言語に比べると相当遅れている印象なので、このあたりが<a class="keyword" href="http://d.hatena.ne.jp/keyword/Ruby">Ruby</a> 3の注力分野の一つになっているのはとてもいいことだと思った。</p> <h1 id="DAP"><a class="keyword" href="http://d.hatena.ne.jp/keyword/DAP">DAP</a></h1> <p>デバッガも<a class="keyword" href="http://d.hatena.ne.jp/keyword/VSCode">VSCode</a>のCodeLLDBみたいな奴使いたいんだよなーと思って調べたところ、<a href="https://github.com/puremourning/vimspector">vimspector</a>というのを使うと<a class="keyword" href="http://d.hatena.ne.jp/keyword/VSCode">VSCode</a>のデバッガ拡張をNeovimに使えるらしい。というのも、LSPみたいな感じで<a class="keyword" href="http://d.hatena.ne.jp/keyword/Microsoft">Microsoft</a>が<a href="https://microsoft.github.io/debug-adapter-protocol/">DAP (Debug Adapter Protocol)</a>というものを提唱しているようで、coc.nvimとvimspectorを使うと、何か<a class="keyword" href="http://d.hatena.ne.jp/keyword/VSCode">VSCode</a>の拡張は大体Neovimでも使えそうだなという雰囲気がある。まだこれは試せてないのでまた今度。</p> <h1 id="まとめ">まとめ</h1> <p>coc.nvimをいれて<a href="https://github.com/neoclide/coc.nvim/wiki/Using-coc-extensions">ここ</a>から<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%D7%A5%E9%A5%B0%A5%A4%A5%F3">プラグイン</a>を探して使うだけで割と<a class="keyword" href="http://d.hatena.ne.jp/keyword/VSCode">VSCode</a>みたいな体験になる。</p> <div class="footnote"> <p class="footnote"><a href="#fn-1d85b5f6" name="f-1d85b5f6" class="footnote-number">*1</a><span class="footnote-delimiter">:</span><span class="footnote-text"><a href="https://www.jetbrains.com/help/idea/discover-intellij-idea.html">https://www.jetbrains.com/help/idea/discover-intellij-idea.html</a> に "<a class="keyword" href="http://d.hatena.ne.jp/keyword/C/C%2B%2B">C/C++</a> are not officially supported in <a class="keyword" href="http://d.hatena.ne.jp/keyword/IntelliJ">IntelliJ</a> IDEA, but you can use CLion" と書いてある</span></p> <p class="footnote"><a href="#fn-754381c4" name="f-754381c4" class="footnote-number">*2</a><span class="footnote-delimiter">:</span><span class="footnote-text">Kotlinに関しては同じ会社が作っている以上は、JetBrainsが作っている<a class="keyword" href="http://d.hatena.ne.jp/keyword/IDE">IDE</a>が一番充実しているという状態は揺るがないと思う</span></p> <p class="footnote"><a href="#fn-0d5f2c01" name="f-0d5f2c01" class="footnote-number">*3</a><span class="footnote-delimiter">:</span><span class="footnote-text"><a href="https://twitter.com/yuki_ycino">ycino</a>さんに教わりました、感謝。一方、最初Neovimにしか対応してなかったことからも、この段落で言ってることは依然としてそれほど外してないように思うので、そのまま残した。</span></p> <p class="footnote"><a href="#fn-d2ce88f0" name="f-d2ce88f0" class="footnote-number">*4</a><span class="footnote-delimiter">:</span><span class="footnote-text">unused importの警告がないとかだったような気がするけど、うろおぼえ。それは最新版では直ってたりするかも</span></p> </div> k0kubun Zigで簡単クロスコンパイル 2022 hatenablog://entry/4207112889906870924 2022-08-12T15:06:01+09:00 2022-08-12T15:07:56+09:00 僕は以下の3つのツールを複数プラットフォーム向けにクロスコンパイルしてバイナリ配布しており、以下のように全て異なる言語で開発している。 Go: sqldef Rust: xremap mruby: mitamae クロスコンパイルに苦労している話をするとZigを使ってみたらいいんじゃないかと言われることがあり、周りでもZigが何となく流行り始めた気がするので、これらのツールに実際自分で使ってみてどうだったかという事例を紹介したい。 Zigとは Zigはそもそもプログラミング言語なのだが、C/C++とのinteropがやりやすい言語なようで、おそらくそれに必要でLLVMベースのC/C++ツールチ… <p>僕は以下の3つのツールを複数プラットフォーム向けにク<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%ED%A5%B9%A5%B3%A5%F3">ロスコン</a>パイルしてバイナリ配布しており、以下のように全て異なる言語で開発している。</p> <ul> <li>Go: <a href="https://github.com/k0kubun/sqldef">sqldef</a></li> <li>Rust: <a href="https://github.com/k0kubun/xremap">xremap</a></li> <li>mruby: <a href="https://github.com/itamae-kitchen/mitamae">mitamae</a></li> </ul> <p>ク<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%ED%A5%B9%A5%B3%A5%F3">ロスコン</a>パイルに苦労している話をするとZigを使ってみたらいいんじゃないかと言われることがあり、周りでもZigが何となく流行り始めた気がするので、これらのツールに実際自分で使ってみてどうだったかという事例を紹介したい。</p> <h1 id="Zigとは">Zigとは</h1> <p>Zigはそもそも<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%D7%A5%ED%A5%B0%A5%E9%A5%DF%A5%F3%A5%B0%B8%C0%B8%EC">プログラミング言語</a>なのだが、<a class="keyword" href="http://d.hatena.ne.jp/keyword/C/C%2B%2B">C/C++</a>との<a class="keyword" href="http://d.hatena.ne.jp/keyword/interop">interop</a>がやりやすい言語なようで、おそらくそれに必要で<a class="keyword" href="http://d.hatena.ne.jp/keyword/LLVM">LLVM</a>ベースの<a class="keyword" href="http://d.hatena.ne.jp/keyword/C/C%2B%2B">C/C++</a>ツールチェインが同梱されていて、しかもそれを<a href="https://andrewkelley.me/post/zig-cc-powerful-drop-in-replacement-gcc-clang.html">Drop-In Replacement for GCC/Clang</a>として売りにしている。</p> <p>僕はZig言語そのものにはそれほど興味はないのだが、ク<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%ED%A5%B9%A5%B3%A5%F3">ロスコン</a>パイラとしての <code>zig cc</code> には強い興味があるので、この記事はその話だけする。</p> <h1 id="使い方">使い方</h1> <h2 id="Go">Go</h2> <p>そもそも前提として、Goは普通は以下のようにするだけでク<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%ED%A5%B9%A5%B3%A5%F3">ロスコン</a>パイルができる。</p> <pre class="code bash" data-lang="bash" data-unlink>CGO_ENABLED=1 GOOS=[GOOS] GOARCH=[GOARCH] go build</pre> <p>問題はCのコードを連携するためにcgoを使う時で、本来cgoは避けるのが賢明なのだが、sqldefで<a class="keyword" href="http://d.hatena.ne.jp/keyword/PostgreSQL">PostgreSQL</a>のパーサーを自分でメンテするのが大変になってきたので<a href="https://github.com/k0kubun/sqldef/pull/241">本家PostgreSQLのCのコードを連携できるライブラリを使う</a>ことにしたため、cgoが必要になってしまった。</p> <p>一方、Zigを使ってク<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%ED%A5%B9%A5%B3%A5%F3">ロスコン</a>パイルするのは簡単で、上記の<a class="keyword" href="http://d.hatena.ne.jp/keyword/%B4%C4%B6%AD%CA%D1%BF%F4">環境変数</a>の他に、以下の<a class="keyword" href="http://d.hatena.ne.jp/keyword/%B4%C4%B6%AD%CA%D1%BF%F4">環境変数</a>を足して <code>go build</code> してやれば良い。target名は <code>zig targets</code> で調べられる。</p> <pre class="code bash" data-lang="bash" data-unlink>CC=&#34;zig cc -target [target]&#34;</pre> <p><a href="https://github.com/k0kubun/sqldef/blob/e3d1a1638825c58358960c8a20f97584a14fc898/.github/workflows/sqldef.yml#L68-L70">GitHub Actions上でのZigのセットアップ</a>が簡単で、targetを設定しなくても使えるのは便利 <a href="#f-be425f3f" name="fn-be425f3f" title="デフォルトのバージョンだとcgoと連携する時にバグがあって動かないので、今は明示的に新しいZigのバージョンを指定する必要があることに注意。それから、Zigに対応するためにはGo側も1.18以上にしないといけない https://github.com/golang/go/issues/43078">*1</a> 。</p> <h3 id="macOSでは動かない"><a class="keyword" href="http://d.hatena.ne.jp/keyword/macOS">macOS</a>では動かない</h3> <p>問題なのは<a class="keyword" href="http://d.hatena.ne.jp/keyword/macOS">macOS</a>をターゲットにする場合で、<a class="keyword" href="http://d.hatena.ne.jp/keyword/MacOSX">MacOSX</a>.<a class="keyword" href="http://d.hatena.ne.jp/keyword/sdk">sdk</a>を自分で調達 <a href="#f-effb7975" name="fn-effb7975" title="https://github.com/phracker/MacOSX-SDKs が便利">*2</a> してきた上で<a href="https://lucor.dev/post/cross-compile-golang-fyne-project-using-zig/">この記事</a>に書いてあるように複雑なフラグを渡さないといけないのだが、そうしてがんばってリンクを成功させても、実行してみると<code>runtime.cgocall</code>でクラッシュしてしまう。元々<a href="https://github.com/ziglang/zig/issues/9050#issuecomment-859939664">macOS向けのZigとcgoの相性はあまり良くなく</a>、色々試したがこれを直すのは無理そうだなと結論づけた。</p> <p><a class="keyword" href="http://d.hatena.ne.jp/keyword/macOS">macOS</a>向けのク<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%ED%A5%B9%A5%B3%A5%F3">ロスコン</a>パイルには<a href="https://github.com/tpoechtrager/osxcross">osxcross</a>というツールがあり、<a class="keyword" href="http://d.hatena.ne.jp/keyword/MacOSX">MacOSX</a>.<a class="keyword" href="http://d.hatena.ne.jp/keyword/sdk">sdk</a>を調達した後これを使って<a href="https://github.com/k0kubun/sqldef/pull/272">clangクロスコンパイラをビルドしそれをCCに指定</a>するとクラッシュしなくなった。</p> <p>実は<a class="keyword" href="http://d.hatena.ne.jp/keyword/Xcode">Xcode</a> 12.2+は元々ク<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%ED%A5%B9%A5%B3%A5%F3">ロスコン</a>パイルに対応しているので、<a class="keyword" href="http://d.hatena.ne.jp/keyword/GitHub">GitHub</a> Actionsで<a class="keyword" href="http://d.hatena.ne.jp/keyword/macos">macos</a>-latestを使うと、<code>CC</code>に何も指定しなくてもarm64向けのcgoク<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%ED%A5%B9%A5%B3%A5%F3">ロスコン</a>パイルができることをその後<a class="keyword" href="http://d.hatena.ne.jp/keyword/vim">vim</a>-jpで教わり、<a href="https://github.com/k0kubun/sqldef/pull/273">そのようにした</a>。現状<a class="keyword" href="http://d.hatena.ne.jp/keyword/macOS">macOS</a>向けのク<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%ED%A5%B9%A5%B3%A5%F3">ロスコン</a>パイルはこれが一番簡単そう。</p> <h2 id="Rust">Rust</h2> <p>Goはlibcにあたる部分も自前で書いているためcgoを使わない限りはク<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%ED%A5%B9%A5%B3%A5%F3">ロスコン</a>パイルが通りやすいのだが、Goとは違ってRustは普通にビルドするとlibcへの依存が発生するため、自分ではネイティブ環境への変な依存を作っていないつもりでもstaticなバイナリの作り方が自明ではなく、ク<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%ED%A5%B9%A5%B3%A5%F3">ロスコン</a>パイルも通しにくかったりする。</p> <h3 id="Just-Work-してくれない">"Just Work" してくれない</h3> <p><a href="https://actually.fyi/posts/zig-makes-rust-cross-compilation-just-work/">Zig Makes Rust Cross-compilation Just Work</a> という記事があり、題名の通りZigを使うとRustのク<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%ED%A5%B9%A5%B3%A5%F3">ロスコン</a>パイルがやりやすくなるそうなので、やってみた。しかし、実際には<a class="keyword" href="http://d.hatena.ne.jp/keyword/glibc">glibc</a>を使う場合もmusl-libcを使う場合もlibcに関係するシンボルがconflictしてしまう。この問題は<a href="https://www.reddit.com/r/rust/comments/q866qx/rust_zig_cc_crt_conflict/">Rust + <code>zig cc</code> CRT conflict.</a>というスレで解説されているが、先ほどの記事でうまくいってるのはlibcがダイナミックリンクされる<a class="keyword" href="http://d.hatena.ne.jp/keyword/macOS">macOS</a>を対象にク<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%ED%A5%B9%A5%B3%A5%F3">ロスコン</a>パイルしているからで、<a class="keyword" href="http://d.hatena.ne.jp/keyword/Linux">Linux</a>や<a class="keyword" href="http://d.hatena.ne.jp/keyword/Windows">Windows</a>だとそうならないためZigが定義するシンボルと衝突するらしい。</p> <h3 id="cross">cross</h3> <p>仕方ないので<a href="https://github.com/cross-rs/cross">cross</a>という既存のク<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%ED%A5%B9%A5%B3%A5%F3">ロスコン</a>パイルツールを使ったらすんなり動いたので、xremapは<a href="https://github.com/k0kubun/xremap/pull/104">crossを使うことにした</a>。以下のようにするだけなので簡単。</p> <pre class="code bash" data-lang="bash" data-unlink>cargo install cross cross build --target=[target]</pre> <h3 id="cargo-zigbuild">cargo-zigbuild</h3> <p>その後rust-lang-jpで<a href="https://github.com/messense/cargo-zigbuild">cargo-zigbuild</a>というのを教わった。これを使えばZigを使ったク<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%ED%A5%B9%A5%B3%A5%F3">ロスコン</a>パイルもうまくいくかもしれない。わざわざcrossから移行するモチベーションはないが、次ク<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%ED%A5%B9%A5%B3%A5%F3">ロスコン</a>パイルを新たに設定する時には試してみようと思っている。</p> <h2 id="mruby">mruby</h2> <p>mrubyはよく使うライブラリが大体Cのコードに依存しており、唯一の<a href="https://github.com/hone/mruby-cli">クロスコンパイルツールチェイン</a>も5年前にメンテがストップしているので、mrubyのク<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%ED%A5%B9%A5%B3%A5%F3">ロスコン</a>パイルは地獄が約束されている。ク<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%ED%A5%B9%A5%B3%A5%F3">ロスコン</a>パイル用の設定の<a class="keyword" href="http://d.hatena.ne.jp/keyword/API">API</a>はあるのだが、そこに渡すク<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%ED%A5%B9%A5%B3%A5%F3">ロスコン</a>パイラは自分で調達しなければならないからだ。</p> <p>そこでZigの出番である。良くも悪くもmrubyはCとの親和性が高いというか、単にCのコードとCで書かれた<a class="keyword" href="http://d.hatena.ne.jp/keyword/VM">VM</a>で動くmrubyの<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%D0%A5%A4%A5%C8%A5%B3%A1%BC%A5%C9">バイトコード</a>の集まりなので、Cのク<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%ED%A5%B9%A5%B3%A5%F3">ロスコン</a>パイラを渡すインターフェースはGoやRustより充実している。以下のように設定すると動く。</p> <pre class="code lang-ruby" data-lang="ruby" data-unlink><span class="synType">MRuby</span>::<span class="synType">CrossBuild</span>.new(<span class="synSpecial">'</span><span class="synConstant">[target]</span><span class="synSpecial">'</span>) <span class="synStatement">do</span> |conf| [conf.cc, conf.linker].each <span class="synStatement">do</span> |cc| cc.command = <span class="synSpecial">'</span><span class="synConstant">zig cc -target [target]</span><span class="synSpecial">'</span> <span class="synStatement">end</span> conf.archiver.command = <span class="synSpecial">'</span><span class="synConstant">zig ar</span><span class="synSpecial">'</span> <span class="synComment"># mrbgems/mruby-yaml や mattn/mruby-onig-regexp にはこれも必要</span> conf.host_target = <span class="synSpecial">'</span><span class="synConstant">[target]</span><span class="synSpecial">'</span> <span class="synStatement">end</span> </pre> <p>mitamaeでは元々<a href="https://github.com/dockcross/dockcross">dockcross</a>を使って<a class="keyword" href="http://d.hatena.ne.jp/keyword/Windows">Windows</a>と<a class="keyword" href="http://d.hatena.ne.jp/keyword/Linux">Linux</a>のバイナリをク<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%ED%A5%B9%A5%B3%A5%F3">ロスコン</a>パイルし、<a href="https://github.com/tpoechtrager/osxcross">osxcross</a>を使って<a class="keyword" href="http://d.hatena.ne.jp/keyword/macOS">macOS</a>のバイナリをク<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%ED%A5%B9%A5%B3%A5%F3">ロスコン</a>パイルしていたのだが、前者はDockerコンテナのメンテ、後者は<a class="keyword" href="http://d.hatena.ne.jp/keyword/MacOSX">MacOSX</a>.<a class="keyword" href="http://d.hatena.ne.jp/keyword/sdk">sdk</a>の調達が面倒だったので、今回の変更でZigをいれるだけで動くようになったのは便利。GoやRustに比べ、mrubyと一緒に使う方が親和性が高く感じた。</p> <h3 id="macOSではzig-ranlibの指定が必要"><a class="keyword" href="http://d.hatena.ne.jp/keyword/macOS">macOS</a>ではzig ranlibの指定が必要</h3> <p>一つだけ注意点としては、<a class="keyword" href="http://d.hatena.ne.jp/keyword/macOS">macOS</a>向けのビルドはranlibを<code>zig ranlib</code>に差し替えないと動かない感じがしており、ranlibを指定する<a class="keyword" href="http://d.hatena.ne.jp/keyword/API">API</a>がmrubyになさそうなので、<code> ENV['RANLIB'] ||= 'zig ranlib'</code> などで無理やり子プロセスに渡るようにしておく必要がある。この設定はどのtargetでも動くので、そこまで困りはしなさそう。</p> <h1 id="まとめ">まとめ</h1> <p>動く環境が限られていたり、特定の言語に向けて設計されたツールと違って連携方法が自明ではなかったりするので、現時点ではそれほど使いやすくはないというのが正直なところ。</p> <p>一方、どれも解決は可能な問題に見えるし、実際過去に他の言語のツールに修正を取り込ませている様子も見えるので、今後便利になると期待している。</p> <div class="footnote"> <p class="footnote"><a href="#fn-be425f3f" name="f-be425f3f" class="footnote-number">*1</a><span class="footnote-delimiter">:</span><span class="footnote-text">デフォルトのバージョンだとcgoと連携する時にバグがあって動かないので、今は明示的に新しいZigのバージョンを指定する必要があることに注意。それから、Zigに対応するためにはGo側も1.18以上にしないといけない <a href="https://github.com/golang/go/issues/43078">https://github.com/golang/go/issues/43078</a></span></p> <p class="footnote"><a href="#fn-effb7975" name="f-effb7975" class="footnote-number">*2</a><span class="footnote-delimiter">:</span><span class="footnote-text"><a href="https://github.com/phracker/MacOSX-SDKs">https://github.com/phracker/MacOSX-SDKs</a> が便利</span></p> </div> k0kubun Treasure Data を退職しました hatenablog://entry/4207112889901850154 2022-07-25T11:03:06+09:00 2022-07-25T13:32:59+09:00 約5年5か月働いたTreasure Dataを7/22に退職した。7/25からShopifyに入社し、RustでJITコンパイラを開発してRubyを高速化する仕事をする。 仕事としてやりたい分野が変わってきて自分は今回転職したけど、とても良い会社なので、この記事がTreasure Data (以下TD) で働くことに興味がある人の参考になれば良いと思っている。*1 5年勤続記念にいただいたトロフィー やっていたこと APIチーム 元々TDにはJavaで分散システムを書きたくて入社したのだが、TD入社前に特にそういう経験があるわけでもなく主にRailsをやっていたこともあり、Railsでプラット… <p>約5年5か月働いたTreasure Dataを7/22に退職した。7/25からShopifyに入社し、Rustで<a class="keyword" href="http://d.hatena.ne.jp/keyword/JIT">JIT</a><a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%B3%A5%F3%A5%D1%A5%A4%A5%E9">コンパイラ</a>を開発して<a class="keyword" href="http://d.hatena.ne.jp/keyword/Ruby">Ruby</a>を高速化する仕事をする。</p> <p>仕事としてやりたい分野が変わってきて自分は今回転職したけど、とても良い会社なので、この記事がTreasure Data (以下TD) で働くことに興味がある人の参考になれば良いと思っている。<a href="#f-cef7909b" name="fn-cef7909b" title="事実、自分の退職が確定してから退職するまでの間に、転職したがっている友人をリファラルでいれようかと試みたりした。自分にリファラルボーナスが入らなくてもおすすめしたいほど良い会社ということ。">*1</a></p> <p><figure class="figure-image figure-image-fotolife" title="5年勤続記念にいただいたトロフィー"><span itemscope itemtype="http://schema.org/Photograph"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/k/k0kubun/20220715/20220715172238.jpg" width="1200" height="900" loading="lazy" title="" class="hatena-fotolife" itemprop="image"></span><figcaption>5年勤続記念にいただいたトロフィー</figcaption></figure></p> <h1>やっていたこと</h1> <h2><a class="keyword" href="http://d.hatena.ne.jp/keyword/API">API</a>チーム</h2> <p>元々TDには<a href="https://k0kubun.hatenablog.com/entry/treasure-data">Javaで分散システムを書きたくて入社した</a>のだが、TD入社前に特にそういう経験があるわけでもなく主に<a class="keyword" href="http://d.hatena.ne.jp/keyword/Rails">Rails</a>をやっていたこともあり、<a class="keyword" href="http://d.hatena.ne.jp/keyword/Rails">Rails</a>でプラットフォームを開発するチームに入った。基盤開発をやりたいと思いながらサービス開発者として最初働き、後に基盤開発チームにジョインするみたいな過去の経験があったので、今回もそういう感じでいけると考えていた。実際このチームには最初の1年だけ所属した後、次のチームに移った。</p> <p>現状<a class="keyword" href="http://d.hatena.ne.jp/keyword/API">API</a>チームにいる人の誰よりもその<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%EA%A5%DD%A5%B8%A5%C8%A5%EA">リポジトリ</a>にコミットしている程度にはその短い期間で色々書いたのだが、おそらく同僚の記憶に残っている仕事は、分散<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%E2%A5%CE%A5%EA%A5%B9">モノリス</a>っぽい設計になっていたせいで障害の温床になっていた<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%EA%A5%DD%A5%B8%A5%C8%A5%EA">リポジトリ</a>の<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%B3%A5%F3%A5%DD%A1%BC%A5%CD%A5%F3%A5%C8">コンポーネント</a>境界を動かし、適切にマイクロサービスとして独立させたことだと思う。この仕事については<a href="https://speakerdeck.com/k0kubun/railsdm2018">RailsDM 2018でも紹介した</a>。</p> <p>ちなみにTDは<a class="keyword" href="http://d.hatena.ne.jp/keyword/Rails">Rails</a>内から<a class="keyword" href="http://d.hatena.ne.jp/keyword/JavaScript">JavaScript</a>フロントエンドを扱わず、完全別<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%EA%A5%DD%A5%B8%A5%C8%A5%EA">リポジトリ</a>で別チームが開発する体制<a href="#f-4270a32e" name="fn-4270a32e" title="Railsのフロントエンド周りは常にわちゃわちゃしているので、それに影響を受けない設計であったのは何かと便利だったと思う">*2</a>なのだが、自分は個人で<a href="https://k0kubun.hatenablog.com/entry/2016/03/21/114626">ReactやReduxを使っていた</a>のもあり、自分で書いた<a class="keyword" href="http://d.hatena.ne.jp/keyword/API">API</a>を呼ぶコンソールを自分で直しに行くこともあった。</p> <p>TDは全然違うチームのプロジェクトに突発的に参加することも割と行なわれていて、例えば「来週から<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%A2%A5%E1%A5%EA">アメリ</a>カに飛んでこれ作ってきて」と当時CTOの太田さんに言われて弾丸で<a href="https://twitter.com/mururururu">@mururururu</a>さんとFluentd関連の<a class="keyword" href="http://d.hatena.ne.jp/keyword/Golang">Golang</a>製プロダクトとそのUIを書いたり、<a href="https://twitter.com/tagomoris">@tagomoris</a>さんがリードしていた<a href="https://www.slideshare.net/tagomoris/planetscale-data-ingestion-pipeline-bigdam/24">Javaで分散システムを書くプロジェクトに入れていただいた</a>りと、色々面白いことができた。</p> <h2>SREチーム</h2> <p>インフラが創業時からあまり変更されておらずデプロイ周りで開発効率があまりにも悪いことが入社時から気になっていて、そのあたりをどうにかする仕事も片手間にやっていたのだが、それを本格的にどうにかしてくれる人を採用できなさそうな雰囲気だったので、SREチームに1年だけ転籍して自分がどうにかすることになった。</p> <p>元々どうなっていたかというと、cronで30分おきにChefが実行され、しかもランダムで失敗するので全台デプロイに最悪数時間かかり、各<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%A4%A5%F3%A5%B9%A5%BF%A5%F3%A5%B9">インスタンス</a>に<a class="keyword" href="http://d.hatena.ne.jp/keyword/ssh">ssh</a>することでデプロイ完了を確認するという感じだった。前の会社の基盤チームで開発していた<a href="https://speakerdeck.com/k0kubun/cookpad-techconf-2017?slide=31">デプロイ環境</a>があまりにも快適だったため、あまりにも失望が大きく、これに近いものをTDにも作ろうと考えていた。</p> <p>SREチームは元々<a class="keyword" href="http://d.hatena.ne.jp/keyword/AWS">AWS</a> CodeDeployを使うための環境をローカルからAnsibleでプロビジョニングする感じで新ツールを作っていたのだが、使いやすさに色々不満があり僕が<a class="keyword" href="http://d.hatena.ne.jp/keyword/AWS">AWS</a> Lambda上にそのスーパーセットとなる<a class="keyword" href="http://d.hatena.ne.jp/keyword/API">API</a>を<a class="keyword" href="http://d.hatena.ne.jp/keyword/Python">Python</a>で書き直した。これでSlackからもwebhookで呼び出せ、インフラの差分更新が細かくできるようにして、今日ではほとんどの開発者に利用されている。<a href="#f-c49048da" name="fn-c49048da" title="一方で、これは短期的に目的を実現するために考えたアーキテクチャなので、長期的にはコンテナベースのデプロイに移行したりもっとコミュニティベースの実装を利用できるように変えた方が良さそうだなあと何度か声を上げていて、2022年の現在では本格的にサービスのデプロイをEKS移行するプロジェクトが動いている。">*3</a></p> <p>基盤を整えた後はChefレシピを<a href="https://github.com/itamae-kitchen/mitamae">mitamae</a>化するなどでせっせと新基盤に移行し、負荷が高い<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%AF%A5%E9%A5%B9%A5%BF">クラスタ</a>のオートスケールを実現したり、<a class="keyword" href="http://d.hatena.ne.jp/keyword/Ubuntu">Ubuntu</a>のバージョン上げたりDocker化したりした時に<a class="keyword" href="http://d.hatena.ne.jp/keyword/Rails">Rails</a>アプリが遅くなったのをどうにかしたりとかした。</p> <h2>Backendチーム</h2> <p>3年目には、当初から入りたかったBackendチームに入ることができた。Backendには4つのサブチームがあり、そのうち主に<a href="https://www.slideshare.net/treasure-data/td-techplazma">PlazmaDB</a>というTD内製のストレージレイヤーを開発するStorageチームに所属し、3年半くらい働いた。</p> <p>TDでは<a class="keyword" href="http://d.hatena.ne.jp/keyword/Hadoop">Hadoop</a>、Presto、Flinkなどの<a class="keyword" href="http://d.hatena.ne.jp/keyword/Java">Java</a>製<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%D5%A5%EC%A1%BC%A5%E0%A5%EF%A1%BC%A5%AF">フレームワーク</a>を扱うことが多く、そのためバックエンドでは<a class="keyword" href="http://d.hatena.ne.jp/keyword/JVM">JVM</a>互換言語が使われていることが多い。昔は大体<a class="keyword" href="http://d.hatena.ne.jp/keyword/Java">Java</a>、その後<a class="keyword" href="http://d.hatena.ne.jp/keyword/Scala">Scala</a>がクエリエンジンチームで流行り、僕がBackendチームに入るころにはKotlinが採用されていて、Backendが作ったサービスのほとんどは今ではKotlinになっている。</p> <p>僕はTDのメインの<a class="keyword" href="http://d.hatena.ne.jp/keyword/Rails">Rails</a>アプリからストレージ関係の機能をマイクロサービスとして切り出す仕事をした後、そのサービスをベースにカラムレベルのアクセスコン<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%C8%A5%ED%A1%BC%A5%EB">トロール</a>をプラットフォーム全体に適用可能にするプロジェクトを1年くらいリードし、あとはPlazmaDBのストレージを最適化するワーカーを書いたり、クエリを最適化するための統計を提供するような仕事をした。</p> <p><a class="keyword" href="http://d.hatena.ne.jp/keyword/API">API</a>チームでご飯を食べに行った時、<a href="https://twitter.com/kamipo">@kamipo</a>さんにBackendに移ったら何をやりたいか聞かれて、ストレージ周りをやりたいという話をした記憶があるが、実際その時想像していたような仕事が最後の方はやれていたように思う。</p> <h1>どんな会社なのか</h1> <h2><a class="keyword" href="http://d.hatena.ne.jp/keyword/OSS">OSS</a>で活躍している人が多い</h2> <p>MessagePack, Fluentd, Embulk, Digdagを生み出した古橋さんを始めとして、<a class="keyword" href="http://d.hatena.ne.jp/keyword/GitHub">GitHub</a>で数百、数千のスターを集める人気<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%EA%A5%DD%A5%B8%A5%C8%A5%EA">リポジトリ</a>の作者が多い。<a class="keyword" href="http://d.hatena.ne.jp/keyword/Ruby">Ruby</a>はここ何年か<a href="https://twitter.com/nalsh">@nalsh</a>さんがリリースマネージャをしているし、今も<a class="keyword" href="http://d.hatena.ne.jp/keyword/Ruby">Ruby</a>コミッタは4人、<a class="keyword" href="http://d.hatena.ne.jp/keyword/Rails">Rails</a>コミッタも1人いる。TDの人が作っている何らかの<a class="keyword" href="http://d.hatena.ne.jp/keyword/OSS">OSS</a>にお世話になっている人は多いのではないだろうか。</p> <p>僕も古橋さんみたいにTDの仕事をきっかけに広く使われる<a class="keyword" href="http://d.hatena.ne.jp/keyword/OSS">OSS</a>を生み出したいという野望があったが、多分一番うまくいったのは、<a href="https://twitter.com/tagomoris">@tagomoris</a>さんのプロジェクト下で<a class="keyword" href="http://d.hatena.ne.jp/keyword/Java">Java</a>でサービスを書きながらRidgepoleの<a class="keyword" href="http://d.hatena.ne.jp/keyword/Ruby">Ruby</a> <a class="keyword" href="http://d.hatena.ne.jp/keyword/DSL">DSL</a>で<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%B9%A5%AD%A1%BC%A5%DE">スキーマ</a>管理をしていたミスマッチ感から思いついた<a href="http://github.com/k0kubun/sqldef">sqldef</a>で、これはありがたいことにいろんな会社で使われている雰囲気を感じる。あとは<a href="https://github.com/k0kubun/rspec-openapi">rspec-openapi</a>も仕事中に思いついたもので、これもちょっと使われていそう。</p> <h2>エンジニアがお金を稼ぎやすい</h2> <p>CEOの太田さんが元々エンジニアで技術力も高く、またTDのビジネスのコアに自社製、他社製問わず<a class="keyword" href="http://d.hatena.ne.jp/keyword/OSS">OSS</a>が使われていることから、エンジニアリングの重要性や難しさを経営陣が深く理解している組織であると思う。その上、TDに入ったエンジニアを全員キャッシュリッチにしたいという話を太田さんは以前していた。</p> <p>TDでは、普段良い仕事をしている人たちは、会社がうまくいった時にドカンとお金をもらえている雰囲気がある。TDがArmに買収されたころ短冊に<a href="https://twitter.com/k0kubun/status/1010752682200403968">一億円と書いたり</a>、<a class="keyword" href="http://d.hatena.ne.jp/keyword/SoftBank">SoftBank</a>の下で再出発となったころは<a href="https://twitter.com/k0kubun/status/1411140330175361031">二億円と書いたり</a>したが、CEOやCTOもこれを見て本気にしてくれるし、いずれもがんばれば現実となるような機会や裁量が与えられていた。転職でこのチャンスを逃すことは残念である。</p> <h2>大規模データの分散処理に挑戦できる</h2> <p>TDは<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%A8%A5%F3%A5%BF%A1%BC%A5%D7%A5%E9%A5%A4%A5%BA">エンタープライズ</a>なお客様にフォーカスしてプロダクトを作っているため、TD自体の会社のサイズは大きくなくとも、大規模なデータを持つお客様を何社も引き受けることになるので、それをマルチテナントで捌いて性能を出すことが求められる。</p> <p>分散DBの性能で<a class="keyword" href="http://d.hatena.ne.jp/keyword/Google">Google</a>や<a class="keyword" href="http://d.hatena.ne.jp/keyword/Amazon">Amazon</a>と全面的に戦う、というような開発投資はしていないが、自分たちのお客様の用途に特化した性能改善は盛んに行なわれており、分散DBの最適化みたいな面白い仕事ができる。単に分散DBそのものを売るよりは、それを活用した周辺ツールとの統合的な体験で価値を生み出すビジネスをしているため、何を最適化するとどうビジネスに<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%A4%A5%F3%A5%D1%A5%AF">インパク</a>トがあるかわかる面白さもある。</p> <p><a href="https://techlife.cookpad.com/entry/2017/10/06/135527">クックパッドのデータ活用基盤</a>をTDからRedshiftに移行した青木峰郎さんが今はTDに所属しているおり、日々楽しそうな仕事をしていることも書いておきたい。</p> <h2>英語や海外移住に挑戦しやすい</h2> <p>日本人が多いので英語話者が日本人の英語アクセントに慣れているだけでなく、人数が多い分英語力も様々であるため、英会話を勉強中の人への許容度が高いように見える。もちろん入社面接では多少英語を話せる必要があるが、それさえ突破してしまうと、無料で英会話レッスンを受ける機会がよく設けられてるし、単純に英語ミーティングの機会が増えるとそのうち慣れる。</p> <p>僕自身、東京オフィスからマウンテンビューオフィスに移籍した組なのだが、どうしても移住がビジネスに必要みたいな状況ではなくとも、<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%BF%A5%A4%A5%E0%A5%BE%A1%BC%A5%F3">タイムゾーン</a>間のバランス調整や知見共有みたいな名目で希望者が時おり北米<a href="#f-7f8feb2f" name="fn-7f8feb2f" title="アメリカのマウンテンビューか、カナダのバンクーバー。最近はバンクーバーに移住する人の方が多い。">*4</a>へ移住していたりする。その際のビザのサポートは会社がやってくれて、初めてのUSビザも<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%B0%A5%EA%A1%BC%A5%F3%A5%AB%A1%BC%A5%C9">グリーンカード</a>も全てTDのサポートで取得させていただいた。</p> <h1>今後やりたいこと</h1> <h2>言語処理系キャリアを築く</h2> <p>僕はこれまで分散システムと言語処理系の2つの技術に主に興味があった。学士論文も分散システムのモデル検査のための言語の<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%B3%A5%F3%A5%D1%A5%A4%A5%E9">コンパイラ</a>を書くものだったので両方に関係している。学部卒業後は仕事で分散システムの開発をしつつ、個人の時間で様々な言語処理系を書く形で両方の分野に常に触れていた。</p> <p><a href="https://k0kubun.hatenablog.com/entry/graduation">社会人を続けながら大学院で勉強</a>し、どちらに関しても複数の授業を取った結果、いずれも人並以上には好きそうだが、最もこだわりがあるのは言語処理系の方であることがわかってきた。その結果、子供が産まれてから仕事以外に使える時間が短くなって必然的に言語処理系に使える時間の比率が下がっていくことにややストレスを感じるようになり、一番興味のある言語処理系の方を仕事にしてそれ一本に集中するのが幸せなのではないかと思うようになり、転職した。</p> <p>言語処理系の開発がそれ自体でお金を生むのは難しく、日本ではそういう仕事はかなり限られてそうに思うが、<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%A2%A5%E1%A5%EA">アメリ</a>カで求人を眺めているとまあまあ面白そうな選択肢があるし、特に<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%B7%A5%EA%A5%B3%A5%F3%A5%D0%A5%EC%A1%BC">シリコンバレー</a>在住で採用してもらう場合は、日本に住んでたら考えられないような待遇が得られる<a href="#f-21adb3f6" name="fn-21adb3f6" title="といっても、無からお金は生まれないので、自分がどのように会社やビジネスにインパクトを与えられているかは常に考え続ける必要があると思う。">*5</a>。片働きで子供を養うことを考えると、これは僕にとっては実質<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%B7%A5%EA%A5%B3%A5%F3%A5%D0%A5%EC%A1%BC">シリコンバレー</a>に来たことで可能になったキャリアと言える。今回のポジションを可能にしたShopifyにもとても感謝している。</p> <h2>3億円貯める</h2> <p>僕は<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%A2%A5%E1%A5%EA">アメリ</a>カに出稼ぎに来ていて、さっさと3億円貯めてリタイアしたいという話は<a href="https://magazine.rubyist.net/articles/0061/0061-Hotlinks.html">Rubyist Hotlinksでのインタビュー</a>で2年前から公言している。この意思は今も変わっていないのだが、妻も僕も主に食が理由でなるべく早く日本に帰りたいという気持ちがあり、あと10年くらい働いた後、子供の学校とかの区切りが良くなったタイミングで日本に帰ろうと思っている。</p> <p>流石にここから10年で資産3億円に達する自信はないのだが、総資産が $2M (約2.7億円) 以上あると<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%B0%A5%EA%A1%BC%A5%F3%A5%AB%A1%BC%A5%C9">グリーンカード</a>を放棄する時に総資産の2割にあたる額を課税されるという話があり、$2M に達する前に帰った方がお得という感じもしており、まあなんか結構稼いだなみたいなところで帰ろうかなという感じ。</p> <h2>ICとして更に昇進する</h2> <p>仕事というのはお金を稼ぐためにやっていることなのでお金は大事だが、一方でそれだけを追求するとメンタルがやられて持続性がなくなるので、TDでは僕は50%の時間を会社の売上や自分の昇進に最適化し、残り50%を自分が技術的に興味のある仕事をやる方に最適化することでバランスを取りながら働いていた。</p> <p>その前者の50%にあたる努力の過程で、昇進のために上司と相談した結果、上司は僕の技術的なスキルには特に不満がなく、かわりに大きなプロジェクトのリードや他チームとの調整をこなしたり他のエンジニアを成長させたりする能力を示すことが求められたため、ここ2年くらいは割とそのような業務の機会をいただくことが多くなった。自分のコミュニケーション能力は特に強みではないと思っているのだが、実際はやってみると周りからの評価が上がったように見えた。</p> <p>これは、自分が得た技術的な知識を自分の仕事に活用するだけでは会社やビジネスに与える<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%A4%A5%F3%A5%D1%A5%AF">インパク</a>トに限りがあり、他の人も自分の能力を活用して仕事がしやすくなるようにすることで、低い労力で大きな成果を生み出すチャンスになるということだと考えている。少し前に<a href="https://twitter.com/__gfx__">@__gfx__</a>さんの<a href="https://engineer-lab.findy-code.io/gfx">ICに関する記事</a>が話題になったが、僕はICというのは生涯現役でコードを書くという側面よりは、昇進するにつれむしろそれ以外のスキルが重要になる<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%AD%A5%E3%A5%EA%A5%A2%A5%D1%A5%B9">キャリアパス</a>だと受け止めている。</p> <p>ICとして昇進するというのは、つまり自分が会社に大きな<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%A4%A5%F3%A5%D1%A5%AF">インパク</a>トを与える能力をつけることだと思っていて、たくさんの利益を生む大きな組織でもそれができるようになれば、仮に自分が直接売上を立てない部門にいても、いっぱいお金をもらう経営的妥当性ができるので収入に直結するため、さっさと3億円貯めて日本で自由に生きるためにもがんばっていきたいと思う。</p> <div class="footnote"> <p class="footnote"><a href="#fn-cef7909b" name="f-cef7909b" class="footnote-number">*1</a><span class="footnote-delimiter">:</span><span class="footnote-text">事実、自分の退職が確定してから退職するまでの間に、転職したがっている友人を<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%EA%A5%D5%A5%A1%A5%E9">リファラ</a>ルでいれようかと試みたりした。自分に<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%EA%A5%D5%A5%A1%A5%E9">リファラ</a>ルボーナスが入らなくてもおすすめしたいほど良い会社ということ。</span></p> <p class="footnote"><a href="#fn-4270a32e" name="f-4270a32e" class="footnote-number">*2</a><span class="footnote-delimiter">:</span><span class="footnote-text"><a class="keyword" href="http://d.hatena.ne.jp/keyword/Rails">Rails</a>のフロントエンド周りは常にわちゃわちゃしているので、それに影響を受けない設計であったのは何かと便利だったと思う</span></p> <p class="footnote"><a href="#fn-c49048da" name="f-c49048da" class="footnote-number">*3</a><span class="footnote-delimiter">:</span><span class="footnote-text">一方で、これは短期的に目的を実現するために考えた<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%A2%A1%BC%A5%AD%A5%C6%A5%AF%A5%C1%A5%E3">アーキテクチャ</a>なので、長期的にはコンテナベースのデプロイに移行したりもっとコミュニティベースの実装を利用できるように変えた方が良さそうだなあと何度か声を上げていて、2022年の現在では本格的にサービスのデプロイをEKS移行するプロジェクトが動いている。</span></p> <p class="footnote"><a href="#fn-7f8feb2f" name="f-7f8feb2f" class="footnote-number">*4</a><span class="footnote-delimiter">:</span><span class="footnote-text"><a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%A2%A5%E1%A5%EA">アメリ</a>カのマウンテンビューか、カナダの<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%D0%A5%F3%A5%AF%A1%BC%A5%D0%A1%BC">バンクーバー</a>。最近は<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%D0%A5%F3%A5%AF%A1%BC%A5%D0%A1%BC">バンクーバー</a>に移住する人の方が多い。</span></p> <p class="footnote"><a href="#fn-21adb3f6" name="f-21adb3f6" class="footnote-number">*5</a><span class="footnote-delimiter">:</span><span class="footnote-text">といっても、無からお金は生まれないので、自分がどのように会社やビジネスに<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%A4%A5%F3%A5%D1%A5%AF">インパク</a>トを与えられているかは常に考え続ける必要があると思う。</span></p> </div> k0kubun 後悔しているがやめられない開発効率向上術 hatenablog://entry/13574176438103981369 2022-06-20T14:29:16+09:00 2022-06-22T13:50:16+09:00 僕はdotfiles系リポジトリ*1のコミット数を合計するだけで2261コミットある、.vimrcばっかりいじっていて開発が全然進まないタイプの人間で、つまり開発環境にとてもこだわりがある。 こだわりすぎて他に誰もやってなさそうな数々のカスタマイズを生み出してしまったが、やらなければよかったと後悔しているものが多くあるので、僕のような人が新たに生まれないよう、やめておけばよかったテクニックとその法則のようなものを紹介したい。 後悔しているもの C-h, C-y, C-u, C-oでウィンドウ切り替え Windows, macOS, Linux問わず以下のグローバルなキーバインドを設定している。… <p>僕はdotfiles系<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%EA%A5%DD%A5%B8%A5%C8%A5%EA">リポジトリ</a><a href="#f-2186fc64" name="fn-2186fc64" title="https://github.com/k0kubun/dotfiles と https://github.com/k0kubun/legacy-dotfiles">*1</a>のコミット数を合計するだけで2261コミットある、.vimrcばっかりいじっていて開発が全然進まないタイプの人間で、つまり開発環境にとてもこだわりがある。</p> <p>こだわりすぎて他に誰もやってなさそうな数々のカスタマイズを生み出してしまったが、やらなければよかったと後悔しているものが多くあるので、僕のような人が新たに生まれないよう、やめておけばよかったテクニックとその法則のようなものを紹介したい。</p> <h1>後悔しているもの</h1> <h2>C-h, C-y, C-u, C-oでウィンドウ切り替え</h2> <p><a class="keyword" href="http://d.hatena.ne.jp/keyword/Windows">Windows</a>, <a class="keyword" href="http://d.hatena.ne.jp/keyword/macOS">macOS</a>, <a class="keyword" href="http://d.hatena.ne.jp/keyword/Linux">Linux</a>問わず以下のグローバルな<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%AD%A1%BC%A5%D0%A5%A4%A5%F3%A5%C9">キーバインド</a>を設定している。</p> <ul> <li>C-h: ターミナルにウィンドウ切り替え</li> <li>C-y: <a class="keyword" href="http://d.hatena.ne.jp/keyword/IntelliJ">IntelliJ</a>かCLionにウィンドウ切り替え</li> <li>C-u: <a class="keyword" href="http://d.hatena.ne.jp/keyword/Google%20Chrome">Google Chrome</a>にウィンドウ切り替え</li> <li>C-o: <a class="keyword" href="http://d.hatena.ne.jp/keyword/Twitter">Twitter</a>かSlackにウィンドウ切り替え</li> </ul> <p><a class="keyword" href="http://d.hatena.ne.jp/keyword/Vim">Vim</a>はターミナル内で起動しており、コードを書いている間基本的に上記4つのウィンドウだけで生活するようにしている。 <a class="keyword" href="http://d.hatena.ne.jp/keyword/macOS">macOS</a>でいうCommand+Tabみたいなショートカットでウィンドウを切り替える場合、まずそれを押してウィンドウがどういう順番で並んでいるか確認し、 その後目的のウィンドウにカーソルが辿りつくまで何度か同じキーを押す必要があり、2アクション以上必要になるが、 このショートカットがあると常に一瞬で目的のウィンドウを開くことができる。</p> <p>何年もこれを使い続けた結果もうやめられなくなっているが、まず (シェルとかで使える) C-uみたいなちょっと便利な機能を潰しているのが困る。<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%DA%A5%A2%A5%D7%A5%ED">ペアプロ</a>相手がC-uを使おうとしてブラウザが開いてびっくりされたことがある。また、見てわかる通りものすごく押しやすい<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%AD%A1%BC%A5%D0%A5%A4%A5%F3%A5%C9">キーバインド</a>を消費しているため、ここに新たに他のウィンドウのショートカットを足そうとすると、似たような押しやすいショートカットを捨てることになる。これは大変だし、そもそもこのショートカットの数が増えると脳が混乱しそうなのでスケールしない。それと、何か新しいデスクトップアプリを使う必要が出てくる度に、諦めるか、ウィンドウ切り替えで不快な思いをすることになる。</p> <p>対案としては、Slackの<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%EF%A1%BC%A5%AF%A5%B9%A5%DA%A1%BC%A5%B9">ワークスペース</a>を切り替えるのと似た感じでCtrl+1, Ctrl+2, ... みたいなもう少しコンフリクトしにくくスケールもしそうな割り当てにするか、まあそもそもこんな方法で生産性向上するのは諦めて大人しくCommand+Tabを使うというのが考えられる (やらなそう)。</p> <h2>半透明背景エディタ</h2> <p>これも全OS共通で、ターミナルの背景は半透明にしている。これは多分学生のころ見た目がかっこいいと思って始めたのだが、実用的なメリットとして、ターミナルを全画面表示にしていてもその裏側のブラウザやSlackに書いてある内容が読めるというものがある。で、気付くとこれに依存した生活をしてしまっていて、<a class="keyword" href="http://d.hatena.ne.jp/keyword/Vim">Vim</a>もターミナルで起動しているためコードを書いている時もブラウザのドキュメントを透し見する癖がついたが、JetBrains <a class="keyword" href="http://d.hatena.ne.jp/keyword/IDE">IDE</a>などの背景が半透明化できないエディタで困ることになった。</p> <p><a class="keyword" href="http://d.hatena.ne.jp/keyword/Linux">Linux</a>ではウィンドウを丸ごと半透明化するのは簡単なのだが、ウィンドウ全体を半透明化するのと背景だけ半透明化するのでは読みやすさが全然違うので話にならないし、<a class="keyword" href="http://d.hatena.ne.jp/keyword/macOS">macOS</a>だとそもそもそれができるツールはOSのバージョンが上がるにつれ動かなくなったりしていった。それから、このウィンドウを重ねて見る生活はタイリングウィンドウマネージャでは実質不可能なことが多く、そういうウィンドウマネージャを選択肢から外すことになる。</p> <p><a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%C7%A5%E5%A5%A2%A5%EB%A5%C7%A5%A3%A5%B9%A5%D7%A5%EC%A5%A4">デュアルディスプレイ</a>はディスプレイ間のマウスカーソルの移動が個人的になんとなく不快なのでいつもシングルディスプレイで作業をしているのだが、対案としては、ワイドディスプレイを使うようにして単にウィンドウを左右に並べるのがよさそうと思っているが、ケチなのでなかなかディスプレイが買えていない。</p> <h2>親指修飾キー</h2> <p>僕のキーボードの修飾キーは以下のような配置にして、全て親指で押している。</p> <pre class="code" data-lang="" data-unlink> [ C ][ V ][ B ][ N ][ M ][ , ] [Ctrl][ Space ][Shift][ Cmd ]</pre> <p>JISのHHKBという、スペースキーがトップクラスに短いキーボードを使っているため、これらの修飾キー全てがとても押しやすい。 何故こうしているかというと、Ctrlは元々Aの左で小指で押していたのだが、<a class="keyword" href="http://d.hatena.ne.jp/keyword/Emacs">Emacs</a>を使っていた時期にこれで小指が痛くなりまくったので、再発防止策として<a class="keyword" href="http://d.hatena.ne.jp/keyword/Vim">Vim</a>に移行したが、それでもシェルや<a class="keyword" href="http://d.hatena.ne.jp/keyword/Vim">Vim</a>以外の場所で<a class="keyword" href="http://d.hatena.ne.jp/keyword/Emacs">Emacs</a><a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%AD%A1%BC%A5%D0%A5%A4%A5%F3%A5%C9">キーバインド</a>を多用していたため、Ctrlを親指で押すようにしたら指が痛くなることがほとんどなくなった。あと<a class="keyword" href="http://d.hatena.ne.jp/keyword/SKK">SKK</a>を使うようになってからShiftキーを多用するようになったが、これも小指が痛くなったので、親指で押すようにした。昔はSandS <a href="#f-63849398" name="fn-63849398" title="Space単押しはSpace、長押しでShiftになる特殊なキーバインド">*2</a> を使っていたが、暴発が多いのでShiftキーは独立させている。</p> <p>これ自体には後悔はないどころか、長く<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%D7%A5%ED%A5%B0%A5%E9%A5%DE">プログラマ</a>を続けるために指の負担を減らすことはとても大切だと思っているが、以下の制約がつくため間接的に後ろめたい気持ちがある。</p> <h2>JISキーボード</h2> <p>親指修飾キーはキーボードがUS配列だととても大変である。上記のキー配置はJIS配のHHKBのものだが、US配列のHHKBはこうなっている。</p> <pre class="code" data-lang="" data-unlink> [ C ][ V ][ B ][ N ][ M ][ , ] [ Space ]</pre> <p>これは特に誇張とかなく本当にこうなっている。つまり、親指を軽く曲げて届く位置に一切修飾キーがない。大体スペース押すのにこんな広い範囲を使い分けるわけないんだから、スペースの無駄遣い<a href="#f-83732bef" name="fn-83732bef" title="pun intended">*3</a>である。</p> <p>JISキーボードを使っていて何が困るかというと、僕はUSに住んでいるのだが、JIS配列のキーボードが居住国で買えなくなる。JIS配列のHHKBを買うために5000円くらい送料をかけてHHKBを買ったことがあるが、<a class="keyword" href="http://d.hatena.ne.jp/keyword/%B3%AB%C9%F5">開封</a>直後買い間違い<a href="#f-6d0ffc2f" name="fn-6d0ffc2f" title="Type-Sを買おうと思ってたらType-Sではなかった。非Type-Sはうるさすぎて子供が寝ている時に使いづらいので、買い直した">*4</a>に気付き、<a class="keyword" href="http://d.hatena.ne.jp/keyword/PFU">PFU</a>は<a class="keyword" href="http://d.hatena.ne.jp/keyword/%B3%AB%C9%F5">開封</a>したら絶対に返品を受けつけないため、もう一度5000円の送料をかけて別のモデルを買うはめになった。それから、USの会社ではJIS配列の<a class="keyword" href="http://d.hatena.ne.jp/keyword/MacBook">MacBook</a>を貸与してくれなかったり、対応していても注文から発送までにものすごく時間がかかったりする。</p> <p>指を痛めるような選択は取れないので、これは今のところどうしようもない。歯を食いしばって法外な送料を払い、返品拒否にも耐え、カンファレンス会場やオンコールなどで外部キーボードを持ち運びたくないがUS配列の<a class="keyword" href="http://d.hatena.ne.jp/keyword/MacBook">MacBook</a>が貸与されている場合は、生産性を落とし指を痛めつつ作業することを覚悟しないといけない。</p> <h2>C-cによる<a class="keyword" href="http://d.hatena.ne.jp/keyword/Vim">Vim</a>のインサートモード抜け</h2> <p>C-cはご存知の通りSIGINTを送るショートカットであるが、<a class="keyword" href="http://d.hatena.ne.jp/keyword/Vim">Vim</a>でインサートモードにいる時にC-cを使うと、何故かインサートモードを抜けてくれる。EscはAの左に配置していて、これでもまあまあ押しやすいし基本的にはそっちを使っているのだが、上記のような修飾キー配置をしていると、現在の指の置き場次第ではC-cがEscよりも押しやすくなってしまう。それで、気付かないうちにEscではなくC-cをたまに使うようになってしまった。実際には Esc や C-[ で抜けるのとは違う挙動になるため、C-cでインサートモードを抜けるのは行儀が悪いだけでなく機能的な不便もある。<a class="keyword" href="http://d.hatena.ne.jp/keyword/Python">Python</a>を使って実装された<a class="keyword" href="http://d.hatena.ne.jp/keyword/Vim">Vim</a><a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%D7%A5%E9%A5%B0%A5%A4%A5%F3">プラグイン</a>を使うと、<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%D7%A5%E9%A5%B0%A5%A4%A5%F3">プラグイン</a>が動いている間にC-cすると例外が発生して<a class="keyword" href="http://d.hatena.ne.jp/keyword/Vim">Vim</a>がエラーになったりする。</p> <p>まあ普通にEsc使えで終わりなのだが、<a class="keyword" href="http://d.hatena.ne.jp/keyword/Vim">Vim</a>でC-cを使って困る状況を意識的に増やさないとなかなか矯正されないかもしれない。</p> <h2><a class="keyword" href="http://d.hatena.ne.jp/keyword/Vim">Vim</a>でしか設定できない<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%AD%A1%BC%A5%D0%A5%A4%A5%F3%A5%C9">キーバインド</a></h2> <p><a class="keyword" href="http://d.hatena.ne.jp/keyword/Vim">Vim</a>では現在のモードに応じて<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%AD%A1%BC%A5%D0%A5%A4%A5%F3%A5%C9">キーバインド</a>を設定できる。インサートモード以外では任意の文字を打ち込む必要がなくなるため、いくつかの普通のキーが何も使われずにおいてある状態になる。従って、スペースキーや<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%BB%A5%DF">セミ</a>コロンなどの大変押しやすいキーをプレフィクスキーにすることができ、具体的には ;u でUnite.<a class="keyword" href="http://d.hatena.ne.jp/keyword/vim">vim</a>を開いたり、スペース→Tで新しいタブを開いたりしている。これで何が困るかというと、<a class="keyword" href="http://d.hatena.ne.jp/keyword/Vim">Vim</a>の外で生活する時にそれと<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%AD%A1%BC%A5%D0%A5%A4%A5%F3%A5%C9">キーバインド</a>を揃えることがとても難しくなる。<a class="keyword" href="http://d.hatena.ne.jp/keyword/IntelliJ">IntelliJ</a>のIdeaVimだと.ideavimrcで似たような設定ができるのだが、IdeaVimが効かないモーダルが開くとそこでは.ideavimrcの設定が使えないので、<a class="keyword" href="http://d.hatena.ne.jp/keyword/Vim">Vim</a>以外で<a class="keyword" href="http://d.hatena.ne.jp/keyword/Vim">Vim</a>と同じ操作感を再現するのが困難になってしまう。</p> <p>対案としては、何か<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%AD%A1%BC%A5%D0%A5%A4%A5%F3%A5%C9">キーバインド</a>を設定するときは<a class="keyword" href="http://d.hatena.ne.jp/keyword/Vim">Vim</a>でしか設定できなそうなものを使うのではなく、普通に修飾キーを組み合わせ、モードに依存しないショートカットにするのが良い。</p> <h2>エディタの垂直分割</h2> <p><a class="keyword" href="http://d.hatena.ne.jp/keyword/Vim">Vim</a>や<a class="keyword" href="http://d.hatena.ne.jp/keyword/IntelliJ">IntelliJ</a>のIdeaVimで:vsし、左右にソースを並べてコードを書くことが結構あるのだが、画面を分割した時の挙動がエディタによって異なるため操作感がかなり変わるのが結構困る。というか、画面を分割した時の<a class="keyword" href="http://d.hatena.ne.jp/keyword/IntelliJ">IntelliJ</a>側の挙動が圧倒的に不便で、垂直分割した後左で関数定義にジャンプする時に左で新たなウィンドウが開くのではなく、右側に同じファイルが開き済みの場合何故か右の画面が遷移してしまい、右に何かを出しっぱなしにして左でコードを書きたいみたいな時に大変不便。</p> <p>そもそも<a class="keyword" href="http://d.hatena.ne.jp/keyword/Vim">Vim</a>だけ使う生活に戻すか、あるいは今<a class="keyword" href="http://d.hatena.ne.jp/keyword/IntelliJ">IntelliJ</a>で書いているものは全て別のエディタ、例えば<a class="keyword" href="http://d.hatena.ne.jp/keyword/VSCode">VSCode</a>で書くように変えようかなとか考えている<a href="#f-feaf88d3" name="fn-feaf88d3" title="VSCodeにこの分割した時の問題があるかどうかはまだ検証できてないので、そうなっていればいいなという希望に過ぎない">*5</a>。</p> <p>7/21 追記: @ka2n さんから "When navigating to a file prefer selecting existing tab in inactive split pane" をオフにするというテクを<a href="https://twitter.com/ka2n/status/1538775068477882370">教わり</a>、これで上述の不満は解消されることがわかった。ただこれが解消されても、<a class="keyword" href="http://d.hatena.ne.jp/keyword/Vim">Vim</a>だとタブごとにペイン分割、<a class="keyword" href="http://d.hatena.ne.jp/keyword/IntelliJ">IntelliJ</a>だとペインごとにタブ分割となる違いは依然として気になっていて、<a class="keyword" href="http://d.hatena.ne.jp/keyword/Vim">Vim</a>の方が挙動的には便利だと思っているが、UI的には<a class="keyword" href="http://d.hatena.ne.jp/keyword/IntelliJ">IntelliJ</a>の方が自然なので、どうしようもないかもしれない。</p> <h1>後悔していないもの</h1> <h2><a class="keyword" href="http://d.hatena.ne.jp/keyword/Emacs">Emacs</a><a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%AD%A1%BC%A5%D0%A5%A4%A5%F3%A5%C9">キーバインド</a></h2> <p>矢印キーは<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%DB%A1%BC%A5%E0%A5%DD%A5%B8%A5%B7%A5%E7%A5%F3">ホームポジション</a>から遠いことが多いので、少なくともその点において、<a class="keyword" href="http://d.hatena.ne.jp/keyword/Emacs">Emacs</a>を使わなくなった今でも<a class="keyword" href="http://d.hatena.ne.jp/keyword/Emacs">Emacs</a><a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%AD%A1%BC%A5%D0%A5%A4%A5%F3%A5%C9">キーバインド</a>は重宝している。 <a class="keyword" href="http://d.hatena.ne.jp/keyword/Emacs">Emacs</a>の C-何とか の<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%AD%A1%BC%A5%D0%A5%A4%A5%F3%A5%C9">キーバインド</a>を奪ってくる不届き者のWebサイトも結構あるのだが、大体キーリマッパ側で矢印キーにリマップしてしまうなどの方法で不便を解消できることが多い。同様にC-a/C-eをHome/Endにリマップしたりするが、これらが微妙に違う挙動をするのは気にならないこともない<a href="#f-810c4cb3" name="fn-810c4cb3" title="物理行頭/末と論理行頭/末の違い">*6</a>のだが、まあ耐えられる範囲。</p> <p>逆にC-x C-sみたいなキーシーケンスとか、マーク機能を利用したリマップに頼るのは、キーリマッパへの依存度が高くなりすぎるのでやめた方がいいだろうと思っていて、やっていない。</p> <p>ちなみに<a class="keyword" href="http://d.hatena.ne.jp/keyword/macOS">macOS</a>は他のOSだとCtrlなショートカットがCommandキーに分離されているから<a class="keyword" href="http://d.hatena.ne.jp/keyword/Emacs">Emacs</a><a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%AD%A1%BC%A5%D0%A5%A4%A5%F3%A5%C9">キーバインド</a>が使いやすく、<a class="keyword" href="http://d.hatena.ne.jp/keyword/Windows">Windows</a>や<a class="keyword" href="http://d.hatena.ne.jp/keyword/Linux">Linux</a>ではそれができないので不便みたいなことを言う人がいるが、Commandキーみたいなものはキーリマッパを使えばいくらでも生み出せるので、そういう人は単にエアプか、キーリマッパでも衝突回避しにくい深淵な使い方をしているかのどちらかだと思う。</p> <h2>非分割キーボード</h2> <p>今現在はノートPCもJIS配列なのだが、外部キーボードとノートPCについてるキーボードがおおむね配列が同じだと、外でノートPCだけで作業する時に操作感が大体同じになってとても便利。分割方法にもよるが、これはErgoDoxとか<a class="keyword" href="http://d.hatena.ne.jp/keyword/Kinesis">Kinesis</a>みたいな特殊な配列をしている分割キーボード<a href="#f-701c99c8" name="fn-701c99c8" title="どちらも過去に使用していた">*7</a>だと、親指周りの操作感が変わってしまってノートPC単体での作業をするとき不便になる。</p> <h2>tmux</h2> <p>ターミナルで複数ウィンドウ・複数タブを使うかわりにtmuxの複数セッション・複数ウィンドウを利用している。個人的にはうっかりターミナルを閉じてもシェルのセッションが保たれる利点にはあまり依存してないのだが、どのOSでも操作感やUIが統一でき、画面の分割も簡単で、コピーモードを使って画面上のどのテキストもキーボード操作だけでコピーできるのがとても便利だと感じている。</p> <h2><a class="keyword" href="http://d.hatena.ne.jp/keyword/SKK">SKK</a></h2> <p>普通の<a class="keyword" href="http://d.hatena.ne.jp/keyword/IME">IME</a>のかわりに<a class="keyword" href="http://d.hatena.ne.jp/keyword/SKK">SKK</a>を使うことで編集効率が上がっているかというとどうなのか何ともいえないが、<a class="keyword" href="http://d.hatena.ne.jp/keyword/SKK">SKK</a>の操作感は<a class="keyword" href="http://d.hatena.ne.jp/keyword/Vim">Vim</a><a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%AD%A1%BC%A5%D0%A5%A4%A5%F3%A5%C9">キーバインド</a>のような気持ちよさが少なくともある。これは他の人のPCを使う時に一見困りそうだが、意外と頭の切り替えがうまくいくし、そこでガッツリ何かを書かないといけないことはほぼないので、後悔することは少ない。<a class="keyword" href="http://d.hatena.ne.jp/keyword/ibus">ibus</a>-<a class="keyword" href="http://d.hatena.ne.jp/keyword/skk">skk</a>、<a class="keyword" href="http://d.hatena.ne.jp/keyword/AquaSKK">AquaSKK</a>、CorvusSKKを使っているが、どれもほぼ同じように操作できるので、移植性はむしろ高い。<a class="keyword" href="http://d.hatena.ne.jp/keyword/ibus">ibus</a>-<a class="keyword" href="http://d.hatena.ne.jp/keyword/skk">skk</a>が全然メンテされてないのは気になるが、<a class="keyword" href="http://d.hatena.ne.jp/keyword/Linux">Linux</a>で使える別実装はいくらでもあるので致命的ではない<a href="#f-5085bd10" name="fn-5085bd10" title="それでもibus-skkを使っているのは、fctix-skkは挙動が遅いと感じるため">*8</a>。</p> <h1>まとめ</h1> <p>要するに大切なのは移植性である。OSやエディタを変えても動く設定を使うのが望ましい。そもそも設定しなくても使えて、PCを初期化したり他の人のPCを使ったりしている時でも可能な操作をするのが理想的。</p> <div class="footnote"> <p class="footnote"><a href="#fn-2186fc64" name="f-2186fc64" class="footnote-number">*1</a><span class="footnote-delimiter">:</span><span class="footnote-text"><a href="https://github.com/k0kubun/dotfiles">https://github.com/k0kubun/dotfiles</a> と <a href="https://github.com/k0kubun/legacy-dotfiles">https://github.com/k0kubun/legacy-dotfiles</a></span></p> <p class="footnote"><a href="#fn-63849398" name="f-63849398" class="footnote-number">*2</a><span class="footnote-delimiter">:</span><span class="footnote-text">Space単押しはSpace、長押しでShiftになる特殊な<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%AD%A1%BC%A5%D0%A5%A4%A5%F3%A5%C9">キーバインド</a></span></p> <p class="footnote"><a href="#fn-83732bef" name="f-83732bef" class="footnote-number">*3</a><span class="footnote-delimiter">:</span><span class="footnote-text">pun intended</span></p> <p class="footnote"><a href="#fn-6d0ffc2f" name="f-6d0ffc2f" class="footnote-number">*4</a><span class="footnote-delimiter">:</span><span class="footnote-text">Type-Sを買おうと思ってたらType-Sではなかった。非Type-Sはうるさすぎて子供が寝ている時に使いづらいので、買い直した</span></p> <p class="footnote"><a href="#fn-feaf88d3" name="f-feaf88d3" class="footnote-number">*5</a><span class="footnote-delimiter">:</span><span class="footnote-text"><a class="keyword" href="http://d.hatena.ne.jp/keyword/VSCode">VSCode</a>にこの分割した時の問題があるかどうかはまだ検証できてないので、そうなっていればいいなという希望に過ぎない</span></p> <p class="footnote"><a href="#fn-810c4cb3" name="f-810c4cb3" class="footnote-number">*6</a><span class="footnote-delimiter">:</span><span class="footnote-text">物理行頭/末と論理行頭/末の違い</span></p> <p class="footnote"><a href="#fn-701c99c8" name="f-701c99c8" class="footnote-number">*7</a><span class="footnote-delimiter">:</span><span class="footnote-text">どちらも過去に使用していた</span></p> <p class="footnote"><a href="#fn-5085bd10" name="f-5085bd10" class="footnote-number">*8</a><span class="footnote-delimiter">:</span><span class="footnote-text">それでも<a class="keyword" href="http://d.hatena.ne.jp/keyword/ibus">ibus</a>-<a class="keyword" href="http://d.hatena.ne.jp/keyword/skk">skk</a>を使っているのは、fctix-<a class="keyword" href="http://d.hatena.ne.jp/keyword/skk">skk</a>は挙動が遅いと感じるため</span></p> </div> k0kubun 働きながらアメリカの大学院でCS修士号を取った hatenablog://entry/13574176438092574267 2022-05-16T12:55:11+09:00 2022-05-18T02:44:33+09:00 4年前に会社の福利厚生を使ってスタンフォードの授業を取ってみたら面白く、 働きながらでも続けられそうだなという実感を得たので、 2年後、受験を経てジョージア工科大学にリモートで通い始めた。 そして先日、ジョージア工科大学からコンピュータサイエンス修士号をいただくことができた。 画像の学位記は卒業式イベント用の非公式のもので、1~2か月すると Masterとちゃんと書いてある本物が来るらしい *1 。 After 1 year and 9 months, I graduated from Georgia Tech and got a master's degree in computer sci… <p>4年前に会社の福利厚生を使って<a href="https://k0kubun.hatenablog.com/entry/stanford-ndo">スタンフォードの授業を取ってみた</a>ら面白く、 働きながらでも続けられそうだなという実感を得たので、 2年後、<a href="https://k0kubun.hatenablog.com/entry/omscs">受験を経てジョージア工科大学にリモートで通い始めた</a>。 そして先日、<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%B8%A5%E7%A1%BC%A5%B8%A5%A2">ジョージア</a>工科大学から<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%B3%A5%F3%A5%D4%A5%E5%A1%BC%A5%BF%A5%B5%A5%A4%A5%A8%A5%F3%A5%B9">コンピュータサイエンス</a><a class="keyword" href="http://d.hatena.ne.jp/keyword/%BD%A4%BB%CE%B9%E6">修士号</a>をいただくことができた。 画像の学位記は卒業式イベント用の<a href="https://commencement.gatech.edu/graduate/masters/takashi-kokubun">非公式のもの</a>で、1~2か月すると Masterとちゃんと書いてある本物が来るらしい <a href="#f-39922a09" name="fn-39922a09" title="この部分は元々注釈で説明していたけど、読まれていなくて誤解が発生していたので、追記で本文に変更した。">*1</a> 。</p> <p><blockquote data-conversation="none" class="twitter-tweet" data-lang="en"><p lang="en" dir="ltr">After 1 year and 9 months, I graduated from <a class="keyword" href="http://d.hatena.ne.jp/keyword/Georgia">Georgia</a> Tech and got a master&#39;s degree in computer science. It was intense to be a student while working full-time, but I learned a lot. <a href="https://t.co/J84JnpGIrp">pic.twitter.com/J84JnpGIrp</a></p>&mdash; k0kubun (@k0kubun) <a href="https://twitter.com/k0kubun/status/1524958514103275520?ref_src=twsrc%5Etfw">May 13, 2022</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script> </p> <p>興味あるしいつかは習得したいんだけどなかなか触る機会がない分野を勉強するついでに、<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%A2%A5%E1%A5%EA">アメリ</a>カでは何かと役に立つ <a href="#f-2c66ea25" name="fn-2c66ea25" title="例えばソフトウェアエンジニアがH1Bという就労ビザを取ろうとすると、アメリカのCS修士があると2回抽選を受けられるが、学士や日本のCS修士では1度しか受けられない。また、グリーンカードを取る際も、学士ではEB-3、修士ではEB-2、博士ではEB-1という風に使える申請カテゴリが変わり、当然より良い学位を持っている方が一般には申請が早く済む。">*2</a> 学位がもらえ、学費は会社の福利厚生でカバーされたし、 <a href="https://www.timeshighereducation.com/world-university-rankings/2022/world-ranking">世界ランキング</a> 45位 の良い大学を2年かからずに卒業できたので良いことづくめだったように思う。</p> <p>この記事では、働きながら<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%B3%A5%F3%A5%D4%A5%E5%A1%BC%A5%BF%A5%B5%A5%A4%A5%A8%A5%F3%A5%B9">コンピュータサイエンス</a>をリモートで学ぶ体験の感想や、授業の面白かった点などをまとめておく。 なお、<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%B8%A5%E7%A1%BC%A5%B8%A5%A2">ジョージア</a>工科大学にも当然ながら普通にキャンパスに通う生徒がいるが、 この記事では本学のCSオンライン受講プログラム<a href="https://omscs.gatech.edu/">OMSCS</a>の話だけ書く。</p> <h1>在学期間</h1> <p>2020秋入学で2022春卒業の計5学期を大学院で過ごした。 生徒だった期間は1年9か月なので、普通に2年かけて<a class="keyword" href="http://d.hatena.ne.jp/keyword/%BD%A4%BB%CE">修士</a>を取る人たちより少し短い期間で学位を取得できたことになる。</p> <p>卒業には10個の授業を取る必要がある。1年に3つの学期があり、春と秋は2つ、夏は1つしか授業を取れないのだが、4つ授業を取った後に成績が良ければ各学期もう1つ授業を追加できるようになる。従って、元々の枠をフルに使い続けるとちょうど2年、6学期で卒業でき、この追加枠を使うと最短5学期で卒業することができる。 <a href="#f-5a56c1aa" name="fn-5a56c1aa" title="どうも基本的に皆フルタイムで働いてるからか、この枠をフルで使い続ける人は少ないようで、多くの人は3-4年かけて卒業するらしい。このプログラムのディレクターであるDavid Joynerに見せてもらったグラフの年では、最短の5学期で卒業したのはたった1%、6学期で卒業したのは5%しかいなかった。YMMV。">*3</a></p> <p>最初の秋学期は子供が産まれた直後 <a href="#f-6b73ca06" name="fn-6b73ca06" title="なので、授業は子供が寝てから自分が寝るまでの時間だけ取り組んでいた。従って平日か休日かに関わらず20-24時の1日4時間が基本という感じだった。">*4</a> だったので様子見で1つしか取らなかったが、翌年春2つ取ってみてもそれほど大変さは変わらないなと思った <a href="#f-17b26766" name="fn-17b26766" title="僕は締切が近付かないとあまり生産性が出ない人間なので、同時に3つ授業を取ると締切の数が3倍になり、従って生産性も3倍になるため効率がよかった。">*5</a> ので、夏に4つ目の授業を取った後は同時に3つ取る学期を2回過ごして卒業要件を満たした。</p> <h1>学費</h1> <p>各学期 $301 かかり、それに加えて各授業 $540 かかる。なので、5学期で10個授業を取ると $6905 で卒業できることになる。</p> <p>これはとんでもなく安い。 <a href="https://k0kubun.hatenablog.com/entry/stanford-ndo">スタンフォードで授業を取った</a> 時は5単位の授業を1つ取るのに $6300 かかり、卒業にはその9倍の単位を取る必要があるが、 <a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%B8%A5%E7%A1%BC%A5%B8%A5%A2">ジョージア</a>工科大学は<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%B9%A5%BF%A5%F3%A5%D5%A5%A9%A1%BC%A5%C9">スタンフォード</a>の授業1.1個分の額で卒業できてしまうことになる。</p> <p><a href="https://shisama.hatenablog.com/entry/2021/12/23/235016">アメリカの無料オンライン大学 University of People</a> という記事を年末見かけたが、これは授業料は無料だが期末試験の受講にトータル $4000 かかるというスキームらしいので、 つまり<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%B8%A5%E7%A1%BC%A5%B8%A5%A2">ジョージア</a>工科大学は"無料"の1.7倍しか費用がかからないことになる。 これは学士のコースの話らしい(コメントで気付いた)ので3.4倍と言う方がフェアかもしれない。</p> <h1>英語</h1> <p>僕は4年前に受けた<a class="keyword" href="http://d.hatena.ne.jp/keyword/TOEIC">TOEIC</a>が845点で、<a class="keyword" href="http://d.hatena.ne.jp/keyword/TOEIC">TOEIC</a>の点数を公言している友達が大体900点台後半なので英語のリーディングとリスニングはどちらかというと自信がない。 一方で、<a href="https://k0kubun.hatenablog.com/entry/omscs">入学した時の記事</a>に<a class="keyword" href="http://d.hatena.ne.jp/keyword/TOEFL">TOEFL</a> iBTが「102点でどの程度授業についていけているかを知りたい」という<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%D6%A5%B3%A5%E1">ブコメ</a>があったが、授業を聴く時も、教科書や論文を読む時も、グループ課題で他の生徒と話す時も、別にそこで苦労したことはなかった。むしろ、割とゆっくり丁寧に話してくれる先生が多いため、授業を1.2〜1.5倍速で再生していることがほとんどだった。</p> <p>これは単に、コンピューターサイエンスに関する話であれば単語は大体知っていて、内容も文脈から推測しやすくなるので、日常英会話とかに比べたら簡単になるという現象な気がする。</p> <h1>授業の感想</h1> <h2>CS6291 Embedded Software Optimization</h2> <p>組み込みシステムの最適化。<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%B3%A5%F3%A5%D1%A5%A4%A5%E9">コンパイラ</a>の授業と同じ先生がやっている。 僕は<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%B3%A5%F3%A5%D1%A5%A4%A5%E9">コンパイラ</a>の中だとバックエンドにしかほぼ興味がなく、この授業は<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%B3%A5%F3%A5%D1%A5%A4%A5%E9">コンパイラ</a>の授業のバックエンド特化版であるという評判を見て、<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%B3%A5%F3%A5%D1%A5%A4%A5%E9">コンパイラ</a>の方ではなくこっちを取ったのだった。 後に結局<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%B3%A5%F3%A5%D1%A5%A4%A5%E9">コンパイラ</a>の方も取ったのだが、<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%EC%A5%B8%A5%B9%A5%BF">レジスタ</a>割付はどちらの授業でもやるものの、命令パイプライニングや分岐予測を考慮した命令のスケジューリングに関して議論されるのはこちらだけなので、その評判は間違ってはいない。ただ、僕の感覚では、<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%B3%A5%F3%A5%D1%A5%A4%A5%E9">コンパイラ</a>をまるごと作った方がやっぱり面白いなと感じた。この授業では<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%EC%A5%B8%A5%B9%A5%BF">レジスタ</a>割付の課題はどの<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%AA%A5%DA%A5%E9%A5%F3%A5%C9">オペランド</a>をどの<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%EC%A5%B8%A5%B9%A5%BF">レジスタ</a>に割り当てるかを決めたら終わりだが、コード生成して<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%D9%A5%F3%A5%C1%A5%DE%A1%BC%A5%AF">ベンチマーク</a>が改善するのを眺める方がよっぽど楽しめる。</p> <h2>CS6200 Graduate Intro to Operating Systems</h2> <p><a class="keyword" href="http://d.hatena.ne.jp/keyword/%BD%A4%BB%CE">修士</a>向けOS入門。学部の時にOSの授業を取りたいと思いつつもいろいろな事情 <a href="#f-62cf6660" name="fn-62cf6660" title="学部の4年間ずっとプログラミングのアルバイトをしていたのだが、さっさと卒業要件を満たして業務のプログラミングに専念する学期を作って社会人に備えたいという謎の危機感があり、3年前期までにほとんどの卒業要件を満たし、3年後期は実際必修を水曜朝1つ取ったらそれ以外はバイトをするという生活を始めたのだった。で、OSの授業はたまたま3年後期に予定されている授業だったため、自分個人の予定と折り合いがつかなかったという感じ。">*6</a> があって取らなかったのだが、この機会にちゃんと基本を抑えておきたいと思って取った。プロセス、スケジューラ、スレッド、メモリ、IOといったそれっぽい話題に大体触れる。OMSCSにはOSの授業が2つあってこれも両方取ったのだが、もう一方はOSそのものについての授業はほとんどないので、OSについて勉強したい人はこちらを取ると良い。が、普段ある程度低レイヤープログラミングをやっている人だと、まあ大体勉強したことあるねみたいな感じの内容ではある。学部時代にOSの授業を取らなかったことから来る不安のようなものが払拭できたのはよかった。</p> <h2>CSE6250 Big Data for Health Informatics</h2> <p><a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%D3%A5%C3%A5%B0%A5%C7%A1%BC%A5%BF">ビッグデータ</a>。授業の名前にあるように<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%D3%A5%C3%A5%B0%A5%C7%A1%BC%A5%BF">ビッグデータ</a>のヘルスケアへの活用に直接興味があるわけではないが、<a class="keyword" href="http://d.hatena.ne.jp/keyword/%B5%A1%B3%A3%B3%D8%BD%AC">機械学習</a>や<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%D3%A5%C3%A5%B0%A5%C7%A1%BC%A5%BF">ビッグデータ</a>について学べる授業なので取った。<a class="keyword" href="http://d.hatena.ne.jp/keyword/%C8%F9%CA%AC">微分</a>や<a class="keyword" href="http://d.hatena.ne.jp/keyword/%C0%FE%B7%C1%C2%E5%BF%F4">線形代数</a>は久しぶりに触れて、大学数学を復習するのに丸一日使うといったことがあった。 この授業を取る前は<a class="keyword" href="http://d.hatena.ne.jp/keyword/%B5%A1%B3%A3%B3%D8%BD%AC">機械学習</a>はやったことがなかったが、かなり広範な技術を一通りカバーする内容になっていて、とても良い入門になった。具体的には、課題を通してNumPy、pandas、scikit-learn、Hive、Pig、Spark、PyTorchの全てに触れるので、<a class="keyword" href="http://d.hatena.ne.jp/keyword/%B5%A1%B3%A3%B3%D8%BD%AC">機械学習</a>と<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%D3%A5%C3%A5%B0%A5%C7%A1%BC%A5%BF">ビッグデータ</a>大体やったことあるなみたいな気分になれる。グループの自由課題では人間の睡眠データから病気になる確率を予測するモデルをPySparkで作ったりした。個人的に面白いと思ったのは生徒間で<a class="keyword" href="http://d.hatena.ne.jp/keyword/%B5%A1%B3%A3%B3%D8%BD%AC">機械学習</a>のモデルの性能をKaggleコンペする課題が2回あることで、しかも順位が成績に影響するところ。公開デー<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%BF%A5%BB%A5%C3%A5%C8">タセット</a>では1位だったが、最終順位が出る非公開デー<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%BF%A5%BB%A5%C3%A5%C8">タセット</a>では一気に29位に落ちるとかあった。</p> <h2>CS7643 <a class="keyword" href="http://d.hatena.ne.jp/keyword/Deep%20Learning">Deep Learning</a></h2> <p><a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%C7%A5%A3%A1%BC%A5%D7%A5%E9%A1%BC%A5%CB%A5%F3%A5%B0">ディープラーニング</a>。この手前に取ったCSE6250でも<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%C7%A5%A3%A1%BC%A5%D7%A5%E9%A1%BC%A5%CB%A5%F3%A5%B0">ディープラーニング</a>に触れはするしPyTorchの使い方くらいは学べるのだが、この分野一つをとってもたくさんの要素技術があるので、ちゃんと<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%C7%A5%A3%A1%BC%A5%D7%A5%E9%A1%BC%A5%CB%A5%F3%A5%B0">ディープラーニング</a>に関して理解したければこの授業を取った方がいいと思われる。人気のある授業で、<a href="https://twitter.com/0xtakp/status/1291164140686528512">割と最近追加された</a>授業なこともあり、かなり新しい論文の内容にも触れるのが良い。<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%D0%A5%C3%A5%AF%A5%D7%A5%ED%A5%D1%A5%B2%A1%BC%A5%B7%A5%E7%A5%F3">バックプロパゲーション</a>の基礎、CNN、言語の<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%E2%A5%C7%A5%EA%A5%F3%A5%B0">モデリング</a>、AttentionやTransformerなどについて学ぶ。 この授業にはKaggleコンペはなかったが、現場で最先端の精度を出すのに使われているモデルはこうやって動いているんだなという意識があり、楽しんで取り組めた。グループ課題では食べ物の写真からレシピを生成するモデルを作った。 <a href="http://pic2recipe.csail.mit.edu/">レシピのデータセット</a>を触ってると、前職<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%AF%A5%C3%A5%AF%A5%D1%A5%C3%A5%C9">クックパッド</a>のレシピも出てきて面白かった。</p> <h2>CS6250 Computer Networks</h2> <p>コンピュータネットワーク。インターネットを支える技術を一通り触る感じ。当然ある程度知ってる話も多かったけど、一度も<a class="keyword" href="http://d.hatena.ne.jp/keyword/TCP/IP">TCP/IP</a>について体系的に学んだことがないみたいな不安がなくなって良い。 BGPとかネットワーク屋さんじゃないと普段触れることはなさそうだし。 インターネットで障害が発生した時に原因についての議論がある程度理解できるようになったり、何かをダウンロードしてくる時の速度の変化について後ろでどういう<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%A2%A5%EB%A5%B4%A5%EA%A5%BA%A5%E0">アルゴリズム</a>が動いてそうなってるのか多少想像することができるようになって楽しい。</p> <h2>CS6515 Intro to Graduate Algorithms</h2> <p><a class="keyword" href="http://d.hatena.ne.jp/keyword/%BD%A4%BB%CE">修士</a>向け<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%A2%A5%EB%A5%B4%A5%EA%A5%BA%A5%E0">アルゴリズム</a>入門。卒業要件を満たすために重要になるため<a class="keyword" href="http://d.hatena.ne.jp/keyword/%CD%FA%BD%A4%C5%D0%CF%BF">履修登録</a>的な意味で人気な授業。僕の場合これが実質必修だったので取ったが、<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%A2%A5%EB%A5%B4%A5%EA%A5%BA%A5%E0">アルゴリズム</a>の問題は純粋なパズル的面白さがあるので楽しめた。 <a class="keyword" href="http://d.hatena.ne.jp/keyword/%C6%B0%C5%AA%B7%D7%B2%E8%CB%A1">動的計画法</a>、分割統治法、<a class="keyword" href="http://d.hatena.ne.jp/keyword/%B9%E2%C2%AE%A5%D5%A1%BC%A5%EA%A5%A8%CA%D1%B4%B9">高速フーリエ変換</a>、<a class="keyword" href="http://d.hatena.ne.jp/keyword/RSA">RSA</a>、グラフ<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%A2%A5%EB%A5%B4%A5%EA%A5%BA%A5%E0">アルゴリズム</a>、最大フロー問題、<a class="keyword" href="http://d.hatena.ne.jp/keyword/%C0%FE%B7%C1%B7%D7%B2%E8%CB%A1">線形計画法</a>、P vs NPなどを扱う。<a href="https://qiita.com/k0kubun/items/e7dbb4ca53f903a38c46">学士で扱うよく聞くようなアルゴリズム</a>は<a class="keyword" href="http://d.hatena.ne.jp/keyword/AtCoder">AtCoder</a>で水色を取る活動をしていた時に復習していたのだが、そこでは学べなかった<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%A2%A5%EB%A5%B4%A5%EA%A5%BA%A5%E0">アルゴリズム</a>をここである程度知れたのはよかった。 こういう知識を活用する頻度が普段そんなに頻繁に発生するわけではないが、スケーラビリティとか計算量の複雑性とかを議論する際、ある程度複雑な理論を理解した経験があると、それより少し易しい話をしている時に確かな自信に裏付けされた議論や心の余裕ができる気がする。</p> <h2>CS8803 Compilers - Theory and Practice</h2> <p><a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%B3%A5%F3%A5%D1%A5%A4%A5%E9">コンパイラ</a>。<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%B3%A5%F3%A5%D1%A5%A4%A5%E9">コンパイラ</a>のフロント、ミドル、バックエンドの理論を全部触り、大学教育に使われる<a class="keyword" href="http://d.hatena.ne.jp/keyword/Tiger">Tiger</a>という<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%D7%A5%ED%A5%B0%A5%E9%A5%DF%A5%F3%A5%B0%B8%C0%B8%EC">プログラミング言語</a>を<a class="keyword" href="http://d.hatena.ne.jp/keyword/MIPS">MIPS</a>に<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%B3%A5%F3%A5%D1%A5%A4%A5%EB">コンパイル</a>する<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%B3%A5%F3%A5%D1%A5%A4%A5%E9">コンパイラ</a>をス<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%AF%A5%E9%A5%C3%A5%C1">クラッチ</a>する課題がある。 正直独学でかなり手を動かしてきた分野なので最初からほとんど知っていたが、あんまりフロントエンドに興味がないのもあり、そこの基礎であるNFAや<a class="keyword" href="http://d.hatena.ne.jp/keyword/DFA">DFA</a>、LLといったところの理論を抑えられたのはよかったと思う(多分自分では勉強しないから)。Ken Thompsonは<a class="keyword" href="http://d.hatena.ne.jp/keyword/%C0%B5%B5%AC%C9%BD%B8%BD">正規表現</a>をNFAに変換する<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%A2%A5%EB%A5%B4%A5%EA%A5%BA%A5%E0">アルゴリズム</a>も発明していてすごいなあとか。</p> <p>僕は過去にいくつか言語処理系を作っているが、大体は<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%A4%A5%F3%A5%BF%A5%D7%A5%EA%A5%BF">インタプリタ</a>でコード生成が不要か、<a class="keyword" href="http://d.hatena.ne.jp/keyword/LLVM">LLVM</a>とかを使ってコード生成をしているとかで、<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%A2%A5%BB%A5%F3%A5%D6%A5%EA">アセンブリ</a>を直接吐く<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%B3%A5%F3%A5%D1%A5%A4%A5%E9">コンパイラ</a>を一から最後まで書き上げた経験がなくて <a href="#f-bd29fd21" name="fn-bd29fd21" title="学部の授業で、先生が用意したx86アセンブリを吐く実装を少し拡張するみたいな課題はやった">*7</a>、それが今回できたのはよかった。<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%EC%A5%B8%A5%B9%A5%BF">レジスタ</a>割付をやるとバックエンドやってる感が出て良い。TAや他の生徒と<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%B3%A5%F3%A5%D1%A5%A4%A5%E9">コンパイラ</a>の性能でランキングを競えるのが楽しかった。</p> <h2>CS6210 Advanced Operating Systems</h2> <p>OSの発展的内容を扱う授業。OSに関しての理解は前提知識とされる授業で、OSそのものに関する授業はほとんどない。 かわりに、OSを使ったシステムデザインや分散システムにひたすら触れるという感じの授業。 毎週3~4つくらいの独立したシステムや<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%A2%A5%EB%A5%B4%A5%EA%A5%BA%A5%E0">アルゴリズム</a>に関する議論が行なわれるので、割と密度が高い。 システムデザインの議論が好きな人は楽しめそうな内容だが、扱われるシステムが結構古かったり、アカデミアの外では使われていないようなものだったりと、よく実用されているシステムの設計について議論する他のクラスに比べるとやや興奮度の低い内容だった。 ただ、分散システムの話題にもある程度触れ、後述する分散システムの授業で何度か言及される授業なので、取っておいたのはよかったと思う。</p> <h2>CS6460 Educational Technology</h2> <p>EdTech。技術の教育への応用という分野には興味はないのだが、これは普通に<a class="keyword" href="http://d.hatena.ne.jp/keyword/%CD%FA%BD%A4%C5%D0%CF%BF">履修登録</a>できるクラスの中で唯一、多少自由にテーマを選んで研究ぽいことができる授業なので、<a class="keyword" href="http://d.hatena.ne.jp/keyword/%BD%A4%BB%CE%CF%C0%CA%B8">修士論文</a>を書かずに卒業するかわりにここで多少研究の経験を積んでおくことにした。 学内の教授と知り合いになると、その先生に一筆書いてもらうことでCS8903というコースを取り普通に研究をして単位をもらうことも可能なのだが、特にそういう関係を築くチャンスもなかったので、気軽に取れる方を取った。</p> <p>実際この授業では論文の見つけ方、論文の読み方などを教わった後、何度も論文ぽいものを書いて添削してもらう経験ができる。ただ、研究そのものの経験はできるものの、研究の成果物は何らかの方法でEdTechに紐付けないといけない。一方、任意のテーマについて教えるコンテンツを作る、といったものでも教育に関連してるとして許容されるため、例えばポーカーの戦略についてまとめるサイトを作っている人もいた。 僕は割と本当にEdTechぽいがちゃんと自分の興味もある課題をひねり出した。具体的には、画像やサイト内のテキストから知らない英単語を抜き出し、任意の辞書で意味を調べ、それを自動で単語帳アプリに登録するみたいなものを作った<a href="#f-1991133c" name="fn-1991133c" title="個人開発を黒字にする技術 https://k0kubun.hatenablog.com/entry/surplus で話していた奴はこれのこと">*8</a>。 英語の語彙が弱いので、単語帳で勉強する労力を下げられるようなものを作れてよかった。</p> <h2>CS7210 Distributed Computing</h2> <p>分散システム。僕が取った奴の中では一番最近追加された授業で、入学時点ではこういう授業がなくてガッカリしていたのだが、取れてよかった。 社内の輪読で割と分散システムに関する論文を読んでいた経験から、これも知っているか業務の経験から理解しているものがちょくちょくあったが、分散システムの基礎的な範囲をいろいろ触っているので知らないものもまあまああり、結構勉強になった。 論理時計、一貫性、<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%EC%A5%D7%A5%EA%A5%B1%A1%BC%A5%B7%A5%E7%A5%F3">レプリケーション</a>、 分散合意などに触れる。<a class="keyword" href="http://d.hatena.ne.jp/keyword/Amazon%20Aurora">Amazon Aurora</a>や<a class="keyword" href="http://d.hatena.ne.jp/keyword/Google">Google</a> Spannerのような、流行りの<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%AF%A5%E9%A5%A6%A5%C9">クラウド</a>が採用している<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%A2%A1%BC%A5%AD%A5%C6%A5%AF%A5%C1%A5%E3">アーキテクチャ</a>に関する議論があるのもとても楽しい。</p> <p>この授業で良いのは全ての宿題を通して分散KVSを作るところ。スケーラビリティのためにシャーディングが可能で、各シャードを扱う<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%AF%A5%E9%A5%B9%A5%BF">クラスタ</a>はPAXOSで書き込みのログをレプリすることで耐故障性を実装し、そしてその<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%AF%A5%E9%A5%B9%A5%BF">クラスタ</a>間で2フェーズコミットを使うことで複数シャードにまたがる分散<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%C8%A5%E9%A5%F3%A5%B6%A5%AF%A5%B7%A5%E7%A5%F3">トランザクション</a>を実装するというもの。で、これを実装する際に分散システムを作る<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%D5%A5%EC%A1%BC%A5%E0%A5%EF%A1%BC%A5%AF">フレームワーク</a>のようなものを使うのだが、それを使って実装すると、その実装で発生する状態遷移の組み合わせを全て検証するテスト、つまりモデル検査(TLA+みたいな奴)のようなことが可能になっていて、あらゆるコーナーケースで分散合意と進捗を保証しないとテストが落ちるようになっていて、これが難しい。分散システムの設計力が真に試される課題で、面白かった。</p> <h2>おすすめ</h2> <p>僕のお気に入りは CS7210 Distributed Computing と CS8803 Compilers。 単に僕個人の好みの分野で選んでいるという感じもあるが、上述したような課題の実装はやったことがなくてやってみたい、という人が受けたら確実に楽しめる内容だと思う。 ちなみに <a href="https://omscentral.com/courses">OMSCentral</a> という授業レビューサイト上では、これらはそれぞれWorkload 1位の授業とDifficulty 1位の授業なので、最難関の授業でもある。楽な授業を取るより、本気で取り組んでやっと満足な成果が出る方が面白い。</p> <h1>成績</h1> <p>GPA: 3.90 / 4.00 だった。<a class="keyword" href="http://d.hatena.ne.jp/keyword/Deep%20Learning">Deep Learning</a>があと0.55点あれば完璧な成績表 <a href="#f-45270d89" name="fn-45270d89" title="点数は残らず、公式な記録はletter gradeしか残らないため">*9</a> になってたのが惜しい気持ちだが、もっと余裕でボーダーを超えられる実力をつけられていなかったので仕方ない。</p> <table> <thead> <tr> <th>学期</th> <th>番号</th> <th>名前</th> <th>Grade</th> <th>点数</th> <th>A要件</th> </tr> </thead> <tbody> <tr> <td>2020 Fall</td> <td>CS6291</td> <td>Embedded Software Optimization</td> <td>A</td> <td>94.96</td> <td>86</td> </tr> <tr> <td rowspan='2'>2021 Spring</td> <td>CS6200</td> <td>Graduate Intro to Operating Systems</td> <td>A</td> <td>87.2</td> <td>80</td> </tr> <tr> <td>CSE6250</td> <td>Big Data for Health Informatics</td> <td>A</td> <td>96.36</td> <td>90</td> </tr> <tr> <td>2021 Summer</td> <td>CS7643</td> <td><a class="keyword" href="http://d.hatena.ne.jp/keyword/Deep%20Learning">Deep Learning</a></td> <td>B</td> <td>88.95</td> <td>89.5</td> </tr> <tr> <td rowspan='3'>2021 Fall</td> <td>CS6250</td> <td>Computer Networks</td> <td>A</td> <td>90.54</td> <td>90</td> </tr> <tr> <td>CS6515</td> <td>Intro to Graduate Algorithms</td> <td>A</td> <td>96.12</td> <td>85</td> </tr> <tr> <td>CS8803</td> <td>Compilers - Theory and Practice</td> <td>A</td> <td>94.23</td> <td>87</td> </tr> <tr> <td rowspan='3'>2022 Spring</td> <td>CS6210</td> <td>Advanced Operating Systems</td> <td>A</td> <td>93.78</td> <td>89.5</td> </tr> <tr> <td>CS6460</td> <td>Educational Technology</td> <td>A</td> <td>96.75</td> <td>90</td> </tr> <tr> <td>CS7210</td> <td>Distributed Computing</td> <td>A</td> <td>89.2</td> <td>84</td> </tr> </tbody> </table> <h1>まとめ</h1> <p>比較的安い授業料でいろいろ学べて楽しい。 <a class="keyword" href="http://d.hatena.ne.jp/keyword/%BD%A4%BB%CE">修士</a>を持っている人や、博士を持っていて他の大学で教師をやっている人もここで生徒をやっていたりするので、もう学位は持ってるという人も気軽に学び直しに来れる場だと思う。</p> <div class="footnote"> <p class="footnote"><a href="#fn-39922a09" name="f-39922a09" class="footnote-number">*1</a><span class="footnote-delimiter">:</span><span class="footnote-text">この部分は元々注釈で説明していたけど、読まれていなくて誤解が発生していたので、追記で本文に変更した。</span></p> <p class="footnote"><a href="#fn-2c66ea25" name="f-2c66ea25" class="footnote-number">*2</a><span class="footnote-delimiter">:</span><span class="footnote-text">例えばソフトウェアエンジニアがH1Bという<a class="keyword" href="http://d.hatena.ne.jp/keyword/%BD%A2%CF%AB%A5%D3%A5%B6">就労ビザ</a>を取ろうとすると、<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%A2%A5%E1%A5%EA">アメリ</a>カのCS<a class="keyword" href="http://d.hatena.ne.jp/keyword/%BD%A4%BB%CE">修士</a>があると2回抽選を受けられるが、学士や日本のCS<a class="keyword" href="http://d.hatena.ne.jp/keyword/%BD%A4%BB%CE">修士</a>では1度しか受けられない。また、<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%B0%A5%EA%A1%BC%A5%F3%A5%AB%A1%BC%A5%C9">グリーンカード</a>を取る際も、学士ではEB-3、<a class="keyword" href="http://d.hatena.ne.jp/keyword/%BD%A4%BB%CE">修士</a>ではEB-2、博士ではEB-1という風に使える申請カテゴリが変わり、当然より良い学位を持っている方が一般には申請が早く済む。</span></p> <p class="footnote"><a href="#fn-5a56c1aa" name="f-5a56c1aa" class="footnote-number">*3</a><span class="footnote-delimiter">:</span><span class="footnote-text">どうも基本的に皆フルタイムで働いてるからか、この枠をフルで使い続ける人は少ないようで、多くの人は3-4年かけて卒業するらしい。このプログラムのディレクターであるDavid Joynerに見せてもらったグラフの年では、最短の5学期で卒業したのはたった1%、6学期で卒業したのは5%しかいなかった。YMMV。</span></p> <p class="footnote"><a href="#fn-6b73ca06" name="f-6b73ca06" class="footnote-number">*4</a><span class="footnote-delimiter">:</span><span class="footnote-text">なので、授業は子供が寝てから自分が寝るまでの時間だけ取り組んでいた。従って平日か休日かに関わらず20-24時の1日4時間が基本という感じだった。</span></p> <p class="footnote"><a href="#fn-17b26766" name="f-17b26766" class="footnote-number">*5</a><span class="footnote-delimiter">:</span><span class="footnote-text">僕は締切が近付かないとあまり生産性が出ない人間なので、同時に3つ授業を取ると締切の数が3倍になり、従って生産性も3倍になるため効率がよかった。</span></p> <p class="footnote"><a href="#fn-62cf6660" name="f-62cf6660" class="footnote-number">*6</a><span class="footnote-delimiter">:</span><span class="footnote-text">学部の4年間ずっとプログラミングのアルバイトをしていたのだが、さっさと卒業要件を満たして業務のプログラミングに専念する学期を作って社会人に備えたいという謎の危機感があり、3年前期までにほとんどの卒業要件を満たし、3年後期は実際必修を水曜朝1つ取ったらそれ以外はバイトをするという生活を始めたのだった。で、OSの授業はたまたま3年後期に予定されている授業だったため、自分個人の予定と折り合いがつかなかったという感じ。</span></p> <p class="footnote"><a href="#fn-bd29fd21" name="f-bd29fd21" class="footnote-number">*7</a><span class="footnote-delimiter">:</span><span class="footnote-text">学部の授業で、先生が用意した<a class="keyword" href="http://d.hatena.ne.jp/keyword/x86">x86</a><a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%A2%A5%BB%A5%F3%A5%D6%A5%EA">アセンブリ</a>を吐く実装を少し拡張するみたいな課題はやった</span></p> <p class="footnote"><a href="#fn-1991133c" name="f-1991133c" class="footnote-number">*8</a><span class="footnote-delimiter">:</span><span class="footnote-text">個人開発を黒字にする技術 <a href="https://k0kubun.hatenablog.com/entry/surplus">https://k0kubun.hatenablog.com/entry/surplus</a> で話していた奴はこれのこと</span></p> <p class="footnote"><a href="#fn-45270d89" name="f-45270d89" class="footnote-number">*9</a><span class="footnote-delimiter">:</span><span class="footnote-text">点数は残らず、公式な記録はletter gradeしか残らないため</span></p> </div> k0kubun 個人開発を黒字にする技術 hatenablog://entry/13574176438089743619 2022-05-06T14:40:04+09:00 2022-05-06T15:00:42+09:00 最近は個人開発は自分のOSSのメンテで手がいっぱいになってしまったのでサービス開発のようなものは普段あまりやらないのだが、大学院*1で今学期、何作ってもよいという感じの授業を取ってWeb/iOS/Androidアプリ*2を全て作るという体験をする中で、たまたま個人開発のコストを抑える活動をしたので、その時に調べたり考えたりしたことを書いておく。 Herokuで無料にする Herokuでは毎月550時間free dynoが使え、クレジットカードを登録しておくと更に450時間、合計1000時間無料で使える。Herokuは30分アクセスがないと一旦停止するが、今回授業で作ったサービスでこれを使い切ら… <p>最近は個人開発は自分の<a class="keyword" href="http://d.hatena.ne.jp/keyword/OSS">OSS</a>のメンテで手がいっぱいになってしまったのでサービス開発のようなものは普段あまりやらないのだが、大学院<a href="#f-6678c03e" name="fn-6678c03e" title="今週期末試験が終わって、点数はまだ確定してないけど、明日卒業式。家庭の事情により出席しないけど">*1</a>で今学期、何作ってもよいという感じの授業を取ってWeb/<a class="keyword" href="http://d.hatena.ne.jp/keyword/iOS">iOS</a>/<a class="keyword" href="http://d.hatena.ne.jp/keyword/Android">Android</a>アプリ<a href="#f-ca9a2b32" name="fn-ca9a2b32" title="厳密にはそれと連携するChrome拡張も作って公開している">*2</a>を全て作るという体験をする中で、たまたま個人開発のコストを抑える活動をしたので、その時に調べたり考えたりしたことを書いておく。</p> <h2>Herokuで無料にする</h2> <p>Herokuでは毎月550時間free dynoが使え、クレジットカードを登録しておくと更に450時間、合計1000時間無料で使える。Herokuは30分アクセスがないと一旦停止するが、今回授業で作ったサービスでこれを使い切らないことは明らかだったので最初はこれでセットアップした。セットアップも簡単だし、<a class="keyword" href="http://d.hatena.ne.jp/keyword/PostgreSQL">PostgreSQL</a>も無料でついてくる。</p> <p>ただ、コールドスタートに10秒くらいかかり、これがこのサービスではUX的に致命的だったため、元々運用していた<a class="keyword" href="http://d.hatena.ne.jp/keyword/VPS">VPS</a>に同居させることで高速化を図った。</p> <h2>安い<a class="keyword" href="http://d.hatena.ne.jp/keyword/VPS">VPS</a>の選定</h2> <p>個人<a class="keyword" href="http://d.hatena.ne.jp/keyword/VPS">VPS</a>は10年くらい持っていて、これまで様々な<a class="keyword" href="http://d.hatena.ne.jp/keyword/VPS">VPS</a>サービスを試してきたが、今回いろいろ整理する前はConoHaを使っていた。最初はDBサーバーと<a class="keyword" href="http://d.hatena.ne.jp/keyword/VPS">VPS</a> 1台で2484円という感じだったが、安くするためにDBを<a class="keyword" href="http://d.hatena.ne.jp/keyword/VPS">VPS</a>同居にして1848円までは圧縮した。</p> <p>ただ、今回もう一つサービスを足すにあたって、当時の<a class="keyword" href="http://d.hatena.ne.jp/keyword/VPS">VPS</a>ではもう一つWebサーバーを立てるほどキャパシティに余裕がなく、かといって家計を削って値段を上げるのもなあという気持ちもあった。そもそも、USに移住したので日本の<a class="keyword" href="http://d.hatena.ne.jp/keyword/VPS">VPS</a>だとレイテンシにやや不満があった。</p> <p>そこで、安くてリソースが多く、可能なら自分に近いリージョンの<a class="keyword" href="http://d.hatena.ne.jp/keyword/VPS">VPS</a>を真面目に調べ直した。結論を書くと、<a href="https://laiso.hatenablog.com/entry/nope-sql">個人開発のコストはDB次第</a>という記事の<a href="https://b.hatena.ne.jp/entry/4719081102410498498/comment/k0kubun">ブコメ</a>にも書いた vCPU 4コア / 8GB RAM / 100GB NVMe <a href="#f-2b035744" name="fn-2b035744" title="本来50GB NVMeか200GB SSDの2択なのだが、契約した当時はその時契約すれば同じ値段でNVMeが2倍の容量使い続けられるというキャンペーンがやっていた">*3</a> で月 $8.24 の<a class="keyword" href="http://d.hatena.ne.jp/keyword/VPS">VPS</a>を発見し、それを使っている。<a href="https://contabo.com/en/vps/">Contabo</a>のCloud <a class="keyword" href="http://d.hatena.ne.jp/keyword/VPS">VPS</a> SのUnited States (Central)がその値段で、<a class="keyword" href="http://d.hatena.ne.jp/keyword/EU">EU</a>だと月 $6.99、Asiaだと月 $9.99 になる。</p> <p>他にもいくつか有望ぽい奴は見つけたが、<a href="https://vpscomp.com/">VPSCOMP</a>というサイトで見つけたものが多かった気がするので、とりあえずこのサイトで好みのやつを探していただくのが良いかもしれない。</p> <h2>サーバーメンテの労力を最小化する</h2> <h3><a class="keyword" href="http://d.hatena.ne.jp/keyword/Kubernetes">Kubernetes</a>をやめる</h3> <p>4年前に練習用途で<a href="https://k0kubun.hatenablog.com/entry/kubernetes">個人サーバーをKubernetes化した</a>のだが、ある日突然<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%AF%A5%E9%A5%B9%A5%BF">クラスタ</a>がクラッシュして再起<a class="keyword" href="http://d.hatena.ne.jp/keyword/%C9%D4%C7%BD">不能</a>になったこともあったりと管理コストが無ではないし、<a class="keyword" href="http://d.hatena.ne.jp/keyword/Kubernetes">Kubernetes</a>そのものがめちゃくちゃリソースを使うのでサーバー代はかさむし、会社で自分のチームがEKSを使い始めて触りたければ触れる状態になったので個人サーバーではやめることにした。今はものすごく素朴に動かしているので、突然何かがクラッシュするみたいな状況は見ないし、したとしてもsystemdがサービスを再起動して勝手に直ると思われる。</p> <h3><a class="keyword" href="http://d.hatena.ne.jp/keyword/%BC%B0%C7%AF%C1%AB%B5%DC">式年遷宮</a>を自動化する</h3> <p>自作プロビジョニングツールである<a href="https://github.com/itamae-kitchen/mitamae">mitamae</a>を使って個人サーバのセットアップを自動化しており、これは何年も秘伝のタレ的に使い続けられている。<a class="keyword" href="http://d.hatena.ne.jp/keyword/Ubuntu">Ubuntu</a>のバージョンを上げる時にdist-upgradeで済ませたこともあるが、サーバーを立て直す労力がそこまで高くないので、<a class="keyword" href="http://d.hatena.ne.jp/keyword/VPS">VPS</a>ごと立て直してしまう<a href="#f-716d0e73" name="fn-716d0e73" title="これを式年遷宮と呼んでいる">*4</a>ことが割とある。これでついでにDBサーバーのバージョンも上がりDBメンテ相当になるが、個人サーバーなので多少のダウンタイムは許容できるし <code>pg_dump</code> してrestoreしてくるけど、9GBほどのDBではすぐ終わる。そんな頻繁に必要なわけじゃないし、<a href="https://laiso.hatenablog.com/entry/nope-sql">例の記事</a>がいうほどDBサーバーのメンテナンスは大変ではない気がしている。</p> <h3>Let's Encryptの自動化</h3> <p>Let's Encryptの証明書が3か月おきに失効するので、これの更新がうまくいっていないのを誰かに指摘されるということが多く、プロビジョニングが自動化された環境下ではこれが一番運用労力がかかっていた印象がある。普通は<a href="https://github.com/certbot/certbot">certbot</a>を使えばいいと思うのだが、何か割とセットアップに手こずった記憶があり、<a class="keyword" href="http://d.hatena.ne.jp/keyword/Ruby">Ruby</a>製の<a href="https://github.com/sorah/acmesmith">acmesmith</a>を使っていて、自分の得意な言語かつ読みやすいサイズなので何かうまく動かなくてもコードを読むことでどうにかしやすくなった。ここ最近は壊れることがなくメンテナンスフリー。</p> <h2><a class="keyword" href="http://d.hatena.ne.jp/keyword/Google%20AdSense">Google AdSense</a>の設置</h2> <p>サイトに広告を一切貼っていなかったころ、<a class="keyword" href="http://d.hatena.ne.jp/keyword/VPS">VPS</a>の運用負荷を下げすぎてほとんど触ることがなくなり、しかもそこで動かしているアプリもそんなに触る動機がない状態になり、金の無駄なので<a class="keyword" href="http://d.hatena.ne.jp/keyword/VPS">VPS</a>を止めるか検討したことがあった。ただ、多少アクセスのあるサイトを動かしていたため、止める前に試しに広告を貼ってみたところ、ConoHaの<a class="keyword" href="http://d.hatena.ne.jp/keyword/VPS">VPS</a>代より売上がコンスタントに出る感じだったので、そうすることにした。</p> <p><a href="https://gitstar-ranking.com/">Gitstar Ranking</a> <a href="#f-809f66d0" name="fn-809f66d0" title="元はGitHub Rankingという名前だったのだが、GitHubに怒られたので変えた">*5</a> という、<a class="keyword" href="http://d.hatena.ne.jp/keyword/GitHub">GitHub</a>のスターの合計数でランキングを出すという非常に浅ましいサービスを8年前に作ったのだが、1日1000~2000PVくらいしかアクセスがないのに毎月$20-30くらい売り上げている。画面全体に出る広告は使っておらず、自分のPCの画面サイズではトップページでファーストビューに入ってこない程度に控えめにしか貼っていないのだが、それでもクリックしてくれる人がいるらしい。</p> <h2>モバイルアプリの公開費用</h2> <p>授業の成果物のため、React Nativeを使って<a class="keyword" href="http://d.hatena.ne.jp/keyword/iOS">iOS</a> / <a class="keyword" href="http://d.hatena.ne.jp/keyword/Android">Android</a>アプリを作ろうとしたところ、作ろうとしているものの要件上やや厳しい感じになり、そこがFlutterでは問題なさそうな感じなので、今回Flutterを使って簡単なモバイルアプリを作った。</p> <p><a class="keyword" href="http://d.hatena.ne.jp/keyword/Dart">Dart</a>とFlutterに関する感想はこの記事ではおいておくが、他の生徒にアプリをテスト公開するにあたり必要になったコストの話を書く。金はかかったが、元々動かしていたサーバーから発生している利益の中には収まってそう。</p> <h3>Firebase</h3> <p>今回作ったアプリでは<a class="keyword" href="http://d.hatena.ne.jp/keyword/Google">Google</a>アカウント認証を使っていて、これは本来Web Viewを使うと別にFirebaseとか使わなくても実装できるのだが、それを実装している<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%B5%A1%BC%A5%C9%A5%D1%A1%BC%A5%C6%A5%A3">サードパーティ</a>のFlutter<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%D7%A5%E9%A5%B0%A5%A4%A5%F3">プラグイン</a>が壊れており、公式が提供しているFlutter<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%D7%A5%E9%A5%B0%A5%A4%A5%F3">プラグイン</a>を使ったところ、流石<a class="keyword" href="http://d.hatena.ne.jp/keyword/Google">Google</a>、これは裏側にFirebaseが使われており、途中から有料になるサービスをまんまと使い始めさせられてしまった。ユーザー100人までは無料で、それに到達しなさそうなのでそのままやっているが、まあいざとなったらFirebaseを気合で外せばよさそう。</p> <h3><a class="keyword" href="http://d.hatena.ne.jp/keyword/Google%20Play">Google Play</a> Developer Program</h3> <p><a class="keyword" href="http://d.hatena.ne.jp/keyword/Android">Android</a>アプリの評価に関してはapkを配布するというのでもよかったのだが、他の生徒がアプリの評価に参加する障壁を下げるため、<a class="keyword" href="http://d.hatena.ne.jp/keyword/Google%20Play">Google Play</a>が公式に提供しているTesting機能を使うことにした。これは $25 払って<a class="keyword" href="http://d.hatena.ne.jp/keyword/Google%20Play">Google Play</a> Developer Programに入らないと使えないが、1回払ったらそれで終わりだし、額的にも<a class="keyword" href="http://d.hatena.ne.jp/keyword/Apple">Apple</a>のそれに比べたらとても良心的だと思う。なおProductionのレビューも通したので今は普通に公開リリースして使っている。</p> <h3><a class="keyword" href="http://d.hatena.ne.jp/keyword/Apple">Apple</a> Developer Program</h3> <p><a class="keyword" href="http://d.hatena.ne.jp/keyword/iOS">iOS</a>アプリの開発でお賃金をもらうのをやめてから9年くらい経つが、少なくともTestFlightにアプリを公開しないと<a class="keyword" href="http://d.hatena.ne.jp/keyword/iOS">iOS</a>ユーザーの生徒にテストしてもらえないため、9年ぶりに再加入した。これはもう更新しないつもりで使っているが、年 $99 というのは高いなあと思う。今はPixelユーザーで次は<a class="keyword" href="http://d.hatena.ne.jp/keyword/iPhone">iPhone</a>にしようか検討しているのだが、自分でアプリを作って使いたくなった時に年 $99 払わされるのは厳しいのでうーむという気持ちになっている。</p> <h2>確定申告</h2> <p>USに住んでるのでありとあらゆるものを確定申告しているのだが、この辺のコストを<a class="keyword" href="http://d.hatena.ne.jp/keyword/AdSense">AdSense</a>の売上の経費として申請すると節税で更にコストが抑えられる。</p> <h2>まとめ</h2> <p>特にマネタイズに気持ちがなくて大して使われてないサービスでも、ほぼ無の運用労力と控えめな広告だけで黒字にでき、それで残りのサービスは自由にやることができる。</p> <div class="footnote"> <p class="footnote"><a href="#fn-6678c03e" name="f-6678c03e" class="footnote-number">*1</a><span class="footnote-delimiter">:</span><span class="footnote-text">今週期末試験が終わって、点数はまだ確定してないけど、明日卒業式。家庭の事情により出席しないけど</span></p> <p class="footnote"><a href="#fn-ca9a2b32" name="f-ca9a2b32" class="footnote-number">*2</a><span class="footnote-delimiter">:</span><span class="footnote-text">厳密にはそれと連携する<a class="keyword" href="http://d.hatena.ne.jp/keyword/Chrome">Chrome</a>拡張も作って公開している</span></p> <p class="footnote"><a href="#fn-2b035744" name="f-2b035744" class="footnote-number">*3</a><span class="footnote-delimiter">:</span><span class="footnote-text">本来50GB NVMeか200GB <a class="keyword" href="http://d.hatena.ne.jp/keyword/SSD">SSD</a>の2択なのだが、契約した当時はその時契約すれば同じ値段でNVMeが2倍の容量使い続けられるというキャンペーンがやっていた</span></p> <p class="footnote"><a href="#fn-716d0e73" name="f-716d0e73" class="footnote-number">*4</a><span class="footnote-delimiter">:</span><span class="footnote-text">これを<a class="keyword" href="http://d.hatena.ne.jp/keyword/%BC%B0%C7%AF%C1%AB%B5%DC">式年遷宮</a>と呼んでいる</span></p> <p class="footnote"><a href="#fn-809f66d0" name="f-809f66d0" class="footnote-number">*5</a><span class="footnote-delimiter">:</span><span class="footnote-text">元は<a class="keyword" href="http://d.hatena.ne.jp/keyword/GitHub">GitHub</a> Rankingという名前だったのだが、<a class="keyword" href="http://d.hatena.ne.jp/keyword/GitHub">GitHub</a>に怒られたので変えた</span></p> </div> k0kubun 2021年にやったこと hatenablog://entry/13574176438045795384 2021-12-24T20:11:34+09:00 2021-12-24T20:22:43+09:00 2020年にやったこと 2019年にやったこと 2018年にやったこと 2017年にやったこと 2016年にやったこと 2015年にやったこと というわけでこれ毎年書いてるんですけど、 なんか参戦したくなったので Rubyist近況 Advent Calendar 2021 24日目です。 入居者募集 記事があるくらいですし、自由に書こうと思います。メリークリスマス。 発表 1歳児がいる状況で家を留守にしたり夜に声を出したりすると家族に負担がかかるので、録画提出できるカンファレンスにしか基本参加しないことにしているのだけど、コロナが長引いていることにより今年も登壇しやすい状況が続いた。 とはい… <ul> <li><a href="https://k0kubun.hatenablog.com/entry/2020-summary">2020年にやったこと</a></li> <li><a href="https://k0kubun.hatenablog.com/entry/2019-summary">2019年にやったこと</a></li> <li><a href="https://k0kubun.hatenablog.com/entry/2018-summary">2018年にやったこと</a></li> <li><a href="https://k0kubun.hatenablog.com/entry/2017-summary">2017年にやったこと</a></li> <li><a href="https://k0kubun.hatenablog.com/entry/2016-summary">2016年にやったこと</a></li> <li><a href="https://k0kubun.hatenablog.com/entry/2015/12/31/000052">2015年にやったこと</a></li> </ul> <p>というわけでこれ毎年書いてるんですけど、 なんか参戦したくなったので <a href="https://adventar.org/calendars/6669">Rubyist近況 Advent Calendar 2021</a> 24日目です。 <a href="https://gist.github.com/amatsuda/538cc9b9a566971220c80e9add6fd035">入居者募集</a> 記事があるくらいですし、自由に書こうと思います。メリークリスマス。</p> <h2>発表</h2> <p>1歳児がいる状況で家を留守にしたり夜に声を出したりすると家族に負担がかかるので、録画提出できるカンファレンスにしか基本参加しないことにしているのだけど、コロナが長引いていることにより今年も登壇しやすい状況が続いた。</p> <p>とはいえ、ハイブリッド開催だったRubyConfに関しては、国内の<a class="keyword" href="http://d.hatena.ne.jp/keyword/%C5%CF%B9%D2">渡航</a>だけでShopifyのYJITチーム全員 (や当地の<a class="keyword" href="http://d.hatena.ne.jp/keyword/Ruby">Ruby</a>フレンズ) と対面で話せる貴重な機会だったので、行けなかったのは惜しいなあと思う。<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%B7%A5%EA%A5%B3%A5%F3%A5%D0%A5%EC%A1%BC">シリコンバレー</a>っていうテックっぽい田舎があるんですが、全てのカンファレンスをここで開催しませんか?</p> <ul> <li>CI/CD Conference 2021: <a href="https://speakerdeck.com/k0kubun/cd-conference-2021">&#x6570;&#x6642;&#x9593;&#x304B;&#x304B;&#x308B;&#x9031;&#x4E00;&#x30EA;&#x30EA;&#x30FC;&#x30B9;&#x3092;&#x6BCE;&#x65E5;&#x4F55;&#x5EA6;&#x3082;&#x7206;&#x901F;&#x3067;&#x3067;&#x304D;&#x308B;&#x3088;&#x3046;&#x306B;&#x3059;&#x308B;&#x307E;&#x3067; / CI/CD Conference 2021 - Speaker Deck</a><a href="https://b.hatena.ne.jp/entry/https://speakerdeck.com/k0kubun/cd-conference-2021" class="http-bookmark"><img src="https://b.hatena.ne.jp/entry/image/https://speakerdeck.com/k0kubun/cd-conference-2021" alt="" class="http-bookmark" /></a></li> <li>RubyKaigi Takeout 2021: <a href="https://speakerdeck.com/k0kubun/rubykaigi-takeout-2021">Why Ruby&#39;s JIT was slow / RubyKaigi Takeout 2021 - Speaker Deck</a><a href="https://b.hatena.ne.jp/entry/https://speakerdeck.com/k0kubun/rubykaigi-takeout-2021" class="http-bookmark"><img src="https://b.hatena.ne.jp/entry/image/https://speakerdeck.com/k0kubun/rubykaigi-takeout-2021" alt="" class="http-bookmark" /></a></li> <li>RubyConf 2021: <a href="https://speakerdeck.com/k0kubun/rubyconf-2021">Optimizing Production Performance with MRI JIT / RubyConf 2021 - Speaker Deck</a><a href="https://b.hatena.ne.jp/entry/https://speakerdeck.com/k0kubun/rubyconf-2021" class="http-bookmark"><img src="https://b.hatena.ne.jp/entry/image/https://speakerdeck.com/k0kubun/rubyconf-2021" alt="" class="http-bookmark" /></a></li> </ul> <p>2015年は10本、2016-2019年は6-7本、2020-2021年は3本というトレンドになってきており、若さからくる勢いを失った感じがするが、そんなことより家族との時間の方が大事である。</p> <p>あと<a class="keyword" href="http://d.hatena.ne.jp/keyword/Ruby">Ruby</a> Roguesという<a class="keyword" href="http://d.hatena.ne.jp/keyword/Podcast">Podcast</a>でまた<a href="https://rubyrogues.com/ruby-jit-and-mjit-ft-takashi-kokubun-ruby-510">話した</a>。2018年に2回話してるので、今回で3回目。5年前にtimakin社長と僕がやっていた<a href="https://bootfm.github.io/">幻のPodcast</a>があって、今も自分でホストできる状況にはないものの、各所からワンショットでゲストとして呼ばれるみたいなのはいつでもお待ちしております。</p> <h2>仕事</h2> <p>初めて職業<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%D7%A5%ED%A5%B0%A5%E9%A5%DE">プログラマ</a>(ただしアルバイト)になったのが2011年5月なので、<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%D7%A5%ED%A5%B0%A5%E9%A5%DE">プログラマ</a>歴10年になった。プロ<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%D7%A5%ED%A5%B0%A5%E9%A5%DE">プログラマ</a>。前前前職と前前職は真面目に大学とサークルをやっていたころだったので勤務時間はあまり長くなく、さっさと単位をほぼ取り終えてサークルをやめ<a href="#f-e83bfb5f" name="fn-e83bfb5f" title="大学公認サークルである学園祭実行委員をやめただけで、それと同時に非公認の東工大音ゲーサークルを立ち上げたので、勤務後や休日のゲーセン通いという名のサークル活動はやっていた">*1</a>、2013年10年から週に1コマだけ取って残りは全部働く<a class="keyword" href="http://d.hatena.ne.jp/keyword/%BC%D2%C3%DC">社畜</a><a href="#f-02a55de0" name="fn-02a55de0" title="バイトの時は有給を取ってなかったので、社会人の時より普通に勤務時間が長かった。実際この時が一番本来の新卒ぽい成長をしていたし、新卒と会社が同じだったことを利用してこの期間がまるでフルタイムのように履歴書やLinkedInで書きがちなのはそのため。書かなかったとしても必要以上に実力を低く見つもられてお互い損するだけな気がする。">*2</a>になりそのまま新卒になったのが前職なので、そういう意味では実質の経験は8年。いやあ、2004年にまだプログラミングも知らず、HTMLを<a class="keyword" href="http://d.hatena.ne.jp/keyword/FFFTP">FFFTP</a>でinfoseekにアップロードして<a href="http://www.t3.rim.or.jp/~naoto/naoto.html">スーパー正男</a>を使ったゲームを公開していたころからここまで長かったですね。</p> <p>で、やっと現職の話をすると、おかげ様で現職よりも待遇が良い会社が<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%B7%A5%EA%A5%B3%A5%F3%A5%D0%A5%EC%A1%BC">シリコンバレー</a>ですら見つけるのが大変な状態まで厚遇されている上、元々やりたかったような仕事に手が届く社内地位を得つつあり、<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%B0%A5%EA%A1%BC%A5%F3%A5%AB%A1%BC%A5%C9">グリーンカード</a>のプロセスをリセットしたくないというのもあって辞めるモチベーションがなさすぎる状態<a href="#f-5d176605" name="fn-5d176605" title="僕の給料を決める権限がある人にこういうのを読まれてしまうと交渉の立場が悪くなるのでこういうのはあまり書かない方が良いのだが、これを読んだとしてもフェアに決めてくれるだろうという信頼が既にある。">*3</a>になり、入社してもう4年半経った。2度目の昇進をしてSeniorの上のStaffというタイトルがつき、今年は1年中とあるプロジェクトのリードをしつつ、その裏で分散システムのスケーラビリティや性能改善のための新<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%B3%A5%F3%A5%DD%A1%BC%A5%CD%A5%F3%A5%C8">コンポーネント</a>開発をやっている。もう触ってないのも含めて、僕が一番コミット数が多いか詳しいみたいな<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%EA%A5%DD%A5%B8%A5%C8%A5%EA">リポジトリ</a>が社内に結構ある<a href="#f-12b85c33" name="fn-12b85c33" title="特にTD APIって奴は、3年前までに1年だけ在籍していたチームのリポジトリなんだけど、何故かそのチーム内にはこれまで僕よりコミットしている人がいなくて、在職者の中で過去に僕よりコミットしたのは古橋さんだけ、僕の次はもうやめたkamipoさん、という渋い状態になっている。僕がリファラルしたmakimotoさんがそろそろkamipoさんを超えそうなので僕も抜いていって欲しい。">*4</a>けど、僕個人のリソースがスケールしないので知識の<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%C8%A5%E9%A5%F3%A5%B9%A5%D5%A5%A1%A1%BC">トランスファー</a>を年中やっている状態なのだが、今のチームで僕の仕事の一つを引き継いだ人が辞めてしまったので、その人がその後やり始めた仕事も増えつつ、結局僕に返ってきた<a href="#f-76392438" name="fn-76392438" title="倍返しだ!! というのはおいといて、この辺をやる僕のチームのSeniorポジションが2月くらいに開くっぽいので、これを読んでる人どうですか? Railsのコードを眺めたりちょっかいを出したりしながら、KotlinでバックエンドのAPIをバリバリ書きまくるみたいなのに興味があるルビーストがいたら是非リファラルしたいのでDMしてください">*5</a>。前職でeagletmt先生が僕に知識を引き継いでいたところを、何故か僕が先に辞め、先輩が僕の書いた<a href="https://github.com/cookpad/barbeque">ジョブキュー</a>を日々メンテするのを眺めている立場なので、文句は言えないと思う。</p> <h2>大学</h2> <p>成績発表〜!</p> <ul> <li>Spring 2021 <ul> <li>CS-6200 - Graduate Intro to OS: A (87.2%)</li> <li><a class="keyword" href="http://d.hatena.ne.jp/keyword/CSE">CSE</a>-6250 - Big Data for Health: A (96.36%)</li> </ul> </li> <li>Summer 2021 <ul> <li>CS-7643 - <a class="keyword" href="http://d.hatena.ne.jp/keyword/Deep%20Learning">Deep Learning</a>: B (88.95%)</li> </ul> </li> <li>Fall 2021 <ul> <li>CS-6250 - Computer Networks: A (90.54%)</li> <li>CS-6515 - Intro to Grad Algorithms: A (96.12%)</li> <li>CS-8803 - Compilers Theory and Practice: A (94.23%)</li> </ul> </li> </ul> <p>ノルマクリア失敗! 全部Aを取るというのを<a href="https://k0kubun.hatenablog.com/entry/2020-summary">今年の目標にしていた</a>のだが、やらかしてしまった。ほとんどのクラスでは僕のやる気と余力と能力が点数に反映されている感じがするが、<a class="keyword" href="http://d.hatena.ne.jp/keyword/Deep%20Learning">Deep Learning</a>に関してはもう不服オブ不服である。授業で説明された理論はおおむね理解しているし、プロジェクトでもものすごい時間を費やしてかなりの理解が得られたが、残念ながら論文のクオリティを上げるといった作業より、コードをいっぱい書いてより多くの成果を出すというあまり点数に関係ないところに時間を使いすぎたようで、他のチームは大体成績がよかったところで大幅に点を削られてしまい、Aに0.55%<a href="#f-2a135bc5" name="fn-2a135bc5" title="予告通りAのボーダー90%はcurveしなかったが、roundはして89.5%以上がAとなったため">*6</a>だけ届かない結果となった。僕は学部時代もコードを一切書かない<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%B3%A5%F3%A5%D1%A5%A4%A5%E9">コンパイラ</a>の授業<a href="#f-01d9e025" name="fn-01d9e025" title="コンパイラを書かないコンパイラの授業とは…? これで実際コンパイラ書けるようになるのか…? と思ったものだが、今もその教科書は持っているので眺めてみたところ、全てコンパイラフロントエンドの理論の話で、これは今回の授業の3つのパートのうち1つ目でカバーされていた。実際、コードを書く授業かに関わらずもともとフロントエンド側には興味がなくてそこだけ知識が薄かったので、実際に(Aを取るために)真面目に勉強してみると勉強になった。それ以外のパートは、特にレジスターアロケーションも何故か同じ教授の授業で全く同じレクチャー(完全にコピペだったので「[違うクラスの名前]にようこそ!」みたいな導入だった)を試聴済みだったのもあり、「知ってた」みたいな感じだった。">*7</a>では点数が悪かったし、コードを書く以外の作業にやる気を出すのが得意でないことは自覚していきたい。</p> <p>これらの授業を通して、OSの<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%A2%A1%BC%A5%AD%A5%C6%A5%AF%A5%C1%A5%E3">アーキテクチャ</a>、<a class="keyword" href="http://d.hatena.ne.jp/keyword/%B5%A1%B3%A3%B3%D8%BD%AC">機械学習</a>、pandas、scikit-learn、<a class="keyword" href="http://d.hatena.ne.jp/keyword/MapReduce">MapReduce</a>、Pig、Spark、<a class="keyword" href="http://d.hatena.ne.jp/keyword/Scala">Scala</a>、DNN、CNN、Transformer、pytorch、<a class="keyword" href="http://d.hatena.ne.jp/keyword/TCP/IP">TCP/IP</a>、<a class="keyword" href="http://d.hatena.ne.jp/keyword/RSA">RSA</a>、<a class="keyword" href="http://d.hatena.ne.jp/keyword/FFT">FFT</a>、P vs NP、LP、NFA、<a class="keyword" href="http://d.hatena.ne.jp/keyword/DFA">DFA</a>、<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%EC%A5%B8%A5%B9%A5%BF">レジスタ</a><a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%A2%A5%ED%A5%B1%A1%BC%A5%B7%A5%E7%A5%F3">アロケーション</a>の実装、<a class="keyword" href="http://d.hatena.ne.jp/keyword/MIPS">MIPS</a><a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%A2%A5%BB%A5%F3%A5%D6%A5%EA">アセンブリ</a>、その他多くを1年で学んだというのは、すごいインプットに倒した1年だったなと思う。学部のプログラミングに関する授業は(元々知ってる)Cと<a class="keyword" href="http://d.hatena.ne.jp/keyword/Java">Java</a>を1年かけて学ぶくらいの速度だったので、フルタイムで学生をやっていた当時よりむしろフルタイム社会人の今年の方がプログラミングについて圧倒的に多くのことを学んだと思う<a href="#f-859bc51d" name="fn-859bc51d" title="プログラミングについて「は」、というのが正しくて、数学とか物理とか文系科目がその他の時間を占めていたため。">*8</a>。成績表でも見せない限り「えー適当に流してたんでしょ?」とか言われそうな詰め込み具合である。全部完全に理解しました™ <a href="#f-9126e7fd" name="fn-9126e7fd" title="まあBを取ってしまったディープラーニングに関してはもう何も言えませんが………">*9</a></p> <p>個別の授業の感想は卒業した後にまとめて書こうと思うが、ハイライトとしては、同じ授業をたまたま同時に取ってた<a href="https://twitter.com/k0kubun/status/1355467607588003842">同僚と機械学習の宿題でKaggleコンペで競った</a>り、2人グループで<a class="keyword" href="http://d.hatena.ne.jp/keyword/Tiger">Tiger</a>→<a class="keyword" href="http://d.hatena.ne.jp/keyword/MIPS">MIPS</a><a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%B3%A5%F3%A5%D1%A5%A4%A5%E9">コンパイラ</a>を書くプロジェクトにソロ参戦して竹内関数の<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%D9%A5%F3%A5%C1%A5%DE%A1%BC%A5%AF">ベンチマーク</a>でランキングを競う奴あたりが個人的に一番楽しかった。春学期にあと3つ授業を取ると卒業できるので、何事もなければトータル5学期(1年9か月)で卒業できる見込み。</p> <h2>US生活</h2> <p>ビザステータスで<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%A2%A5%E1%A5%EA">アメリ</a>カに入国してから2年が経った。コロナで家賃が下がって、立地も治安もよいリノベ直後の2ベッドルーム<a href="#f-93fea1ec" name="fn-93fea1ec" title="西日暮里で住んでた2DKの1.5倍くらい広い">*10</a>を $2,550/mo という安すぎる意味不明の家賃で確保してからというもの、更新の時に賃上げするんじゃないかとビクビクしていたが、今月の更新で家賃は上がらなかった。便利すぎる。<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%B0%A5%EA%A1%BC%A5%F3%A5%AB%A1%BC%A5%C9">グリーンカード</a>のプロセスも大変そうだなあというイメージがあったけど、既に最終ステージで指紋採取も健康診断も終え、コロナで面接はないことになってるので、早ければ来年<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%B0%A5%EA%A1%BC%A5%F3%A5%AB%A1%BC%A5%C9">グリーンカード</a>が取れそうな状態になった。トランプ政権が終わったので途中でビザのプロセスが遅くなったり厳しくなったりするみたいな可能性も低くなってそう。</p> <p>車に子供を長時間乗せると睡眠や機嫌のコン<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%C8%A5%ED%A1%BC%A5%EB">トロール</a>が大変なので、家から車で10分以上かかるところにはほぼ行ってなくて、基本的に公園とスーパーと外食のテイクアウトにしか行かない生活をしている。外食は育児上の苦労が多いのとそもそも僕がケチなところもあり、コロナもある状況下の楽しみとして、料理に大分凝るようになった。これまで手を出してなかった揚げ物や低温調理など。いい奴を作りたい時は結構料理系YouTuberの動画を見てるんだけど、ステーキの焼き方が一番<a href="https://twitter.com/k0kubun/status/1469765789511131137">改善した</a>気がする。同僚のtaroleoさんの<a class="keyword" href="http://d.hatena.ne.jp/keyword/facebook">facebook</a>記事を読んでreverse sear的な焼き方を学んだ時は「焼き目をつける」という工程をちゃんと理解できてなかった感じがするが、中に火を通す工程をじっくり終わらせて、その後表面だけを超高温で短時間加熱して<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%AB%A5%EA%A5%AB">カリカ</a>リにすると、食感が大分おいしい感じになる。</p> <p>ところで去年は、ゲーセンが治安が最悪のところにしか<a class="keyword" href="http://d.hatena.ne.jp/keyword/%B2%BB%A5%B2%A1%BC">音ゲー</a>が置いてあるゲーセンがないと<a href="https://k0kubun.hatenablog.com/entry/2020-summary">書いた</a>が、SF<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%D9%A5%A4%A5%A8%A5%EA%A5%A2">ベイエリア</a>にいながら<a class="keyword" href="http://d.hatena.ne.jp/keyword/IIDX">IIDX</a>両皆伝を維持しているnobu_kさんに僕が懸念していた地域は実際には治安が良いと教えてもらった。ワクチン摂取が急速に進み全てがオープンになったころ、家族が留守にしていたタイミングでRound 1に行って、<a class="keyword" href="http://d.hatena.ne.jp/keyword/IIDX">IIDX</a> SP八段は取ってきた。ちなみに<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%A2%A5%E1%A5%EA">アメリ</a>カでは<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%B3%A5%F3%A5%DE%A5%A4">コンマイ</a>のネットワークをラウワンが独占契約してるらしく、型落ちでない<a href="#f-5ff75cfb" name="fn-5ff75cfb" title="型落ちDDRとかIIDXじゃないbeatmaniaは結構ある">*11</a><a class="keyword" href="http://d.hatena.ne.jp/keyword/%B2%BB%A5%B2%A1%BC">音ゲー</a>をするには今はラウワンに行くしかないらしい。あと、テキサス<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%DB%A1%BC%A5%EB%A5%C7%A5%E0">ホールデム</a>のルールを覚えたので、ついでにカジノにも行って、一番レートの低い4/8 Limit卓のMin Buy-in $40 をそのままスッて来た。</p> <p>ポーカーは地獄のようなセンスだが、資産運用はどうやら人並程度にはできるようになってきたようで、東京のソフトウェアエンジニアの年収くらいの利益はカタい状態になった。まあ、それでは家族3人<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%D9%A5%A4%A5%A8%A5%EA%A5%A2">ベイエリア</a>で暮らしていくというのはできないので、まだまだ無限にお金を稼がないといけない感じがある。</p> <h2>ブログ</h2> <p>CI/CD Conの発表 <a href="https://speakerdeck.com/k0kubun/cd-conference-2021">&#x6570;&#x6642;&#x9593;&#x304B;&#x304B;&#x308B;&#x9031;&#x4E00;&#x30EA;&#x30EA;&#x30FC;&#x30B9;&#x3092;&#x6BCE;&#x65E5;&#x4F55;&#x5EA6;&#x3082;&#x7206;&#x901F;&#x3067;&#x3067;&#x304D;&#x308B;&#x3088;&#x3046;&#x306B;&#x3059;&#x308B;&#x307E;&#x3067; / CI/CD Conference 2021 - Speaker Deck</a><a href="https://b.hatena.ne.jp/entry/https://speakerdeck.com/k0kubun/cd-conference-2021" class="http-bookmark"><img src="https://b.hatena.ne.jp/entry/image/https://speakerdeck.com/k0kubun/cd-conference-2021" alt="" class="http-bookmark" /></a> が一番伸びてて、ブログの方はボチボチという感じなのだが、その中では以下が伸びた方。</p> <ul> <li><a href="https://k0kubun.hatenablog.com/entry/desktop-os">&#x307E;&#x3060;&#x30D1;&#x30BD;&#x30B3;&#x30F3;&#x306E;OS&#x9078;&#x3073;&#x3067;&#x6D88;&#x8017;&#x3057;&#x3066;&#x308B;&#x306E;&#xFF1F; - k0kubun&#39;s blog</a><a href="https://b.hatena.ne.jp/entry/https://k0kubun.hatenablog.com/entry/desktop-os" class="http-bookmark"><img src="https://b.hatena.ne.jp/entry/image/https://k0kubun.hatenablog.com/entry/desktop-os" alt="" class="http-bookmark" /></a></li> <li><a href="https://k0kubun.hatenablog.com/entry/2021/04/02/211455">Pry&#x306F;&#x3082;&#x3046;&#x53E4;&#x3044;&#x3001;&#x6642;&#x4EE3;&#x306F;IRB - k0kubun&#39;s blog</a><a href="https://b.hatena.ne.jp/entry/https://k0kubun.hatenablog.com/entry/2021/04/02/211455" class="http-bookmark"><img src="https://b.hatena.ne.jp/entry/image/https://k0kubun.hatenablog.com/entry/2021/04/02/211455" alt="" class="http-bookmark" /></a></li> <li><a href="https://k0kubun.hatenablog.com/entry/xremap">Linux&#x7528;&#x30AD;&#x30FC;&#x30EA;&#x30DE;&#x30C3;&#x30D1;&#x30FC;xremap&#x3092;Rust&#x3067;&#x66F8;&#x304D;&#x76F4;&#x3057;&#x305F; - k0kubun&#39;s blog</a><a href="https://b.hatena.ne.jp/entry/https://k0kubun.hatenablog.com/entry/xremap" class="http-bookmark"><img src="https://b.hatena.ne.jp/entry/image/https://k0kubun.hatenablog.com/entry/xremap" alt="" class="http-bookmark" /></a></li> <li><a href="https://k0kubun.hatenablog.com/entry/vimrc-2021">8&#x5E74;&#x3076;&#x308A;&#x306B; vimrc &#x3092;&#x66F8;&#x304D;&#x76F4;&#x3057;&#x305F; - k0kubun&#39;s blog</a><a href="https://b.hatena.ne.jp/entry/https://k0kubun.hatenablog.com/entry/vimrc-2021" class="http-bookmark"><img src="https://b.hatena.ne.jp/entry/image/https://k0kubun.hatenablog.com/entry/vimrc-2021" alt="" class="http-bookmark" /></a></li> <li><a href="https://k0kubun.hatenablog.com/entry/gitstar-ranking">Java, MySQL&#x3092;Kotlin, PostgreSQL&#x306B;&#x79FB;&#x884C;&#x3057;&#x305F; - k0kubun&#39;s blog</a><a href="https://b.hatena.ne.jp/entry/https://k0kubun.hatenablog.com/entry/gitstar-ranking" class="http-bookmark"><img src="https://b.hatena.ne.jp/entry/image/https://k0kubun.hatenablog.com/entry/gitstar-ranking" alt="" class="http-bookmark" /></a></li> </ul> <p>ところで、学生のころにQiitaに書いた <a href="https://qiita.com/k0kubun/items/80c5a5494f53bb88dc58">ActiveRecord&#x306E;joins&#x3068;preload&#x3068;includes&#x3068;eager_load&#x306E;&#x9055;&#x3044; - Qiita</a><a href="https://b.hatena.ne.jp/entry/https://qiita.com/k0kubun/items/80c5a5494f53bb88dc58" class="http-bookmark"><img src="https://b.hatena.ne.jp/entry/image/https://qiita.com/k0kubun/items/80c5a5494f53bb88dc58" alt="" class="http-bookmark" /></a> が今でも色な人にincludesとかの説明資料として使っていただけているらしく、これを含めたその他いくつかの昔の記事が伸びていたおかげで、10k subs YouTuberの盾みたいな奴をIncrements社からいただいた。</p> <p><blockquote data-conversation="none" class="twitter-tweet" data-lang="en"><p lang="und" dir="ltr">🥈 <a href="https://t.co/D99kyEqpKD">https://t.co/D99kyEqpKD</a> <a href="https://t.co/nXkSwDGOUq">pic.twitter.com/nXkSwDGOUq</a></p>&mdash; k0kubun (@k0kubun) <a href="https://twitter.com/k0kubun/status/1468069073040773121?ref_src=twsrc%5Etfw">December 7, 2021</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script> </p> <p>しかし最近は人気YouTuberかのような活動は一切しておらず、超純粋に自分の備忘録としてのみQiitaを使っているため、ブログより多く書いてる割には<a href="https://qiita.com/k0kubun">最近の記事</a>はLGTMが0とか1みたいな記事がほとんどである。ただ、もとからそういうコンセプトで続けていることによって、書くクオリティにプレッシャーがかからず自由に書けるのが便利なので、自分の記憶のためにこのスタンスは続けていきたい。それだけだと<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%D5%A5%EA%A1%BC%A5%E9%A5%A4%A5%C0%A1%BC">フリーライダー</a>っぽいので、たまに記事がヒットしてIncrements社に利便性の対価が還元できると良いですね。</p> <h2><a class="keyword" href="http://d.hatena.ne.jp/keyword/OSS">OSS</a>活動</h2> <p>MJITで<a class="keyword" href="http://d.hatena.ne.jp/keyword/Rails">Rails</a>を速くできるようにしたいというのは<a href="https://k0kubun.hatenablog.com/entry/2017-summary">2017年</a>から<a href="https://k0kubun.hatenablog.com/entry/2018-summary">毎年</a>、<a href="https://k0kubun.hatenablog.com/entry/2019-summary">毎年</a>、<a href="https://k0kubun.hatenablog.com/entry/2020-summary">本当に毎年</a>目標にしていたのだが、今年ついにそのパズルを解き、4年間にわたって取り組み続けていた<a href="https://k0kubun.medium.com/ruby-3-jit-can-make-rails-faster-756310f235a">目標を達成した</a>。だが、逆説的に、なぜ遅かったかを理解した瞬間、「ああ、この方針はダメだな」と悟ったので、CRubyではC<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%B3%A5%F3%A5%D1%A5%A4%A5%E9">コンパイラ</a>+dlopenで<a class="keyword" href="http://d.hatena.ne.jp/keyword/JIT">JIT</a>をするのはやめようという方針で活動している。で、YJITという別の<a class="keyword" href="http://d.hatena.ne.jp/keyword/JIT">JIT</a>を開発し始めたShopifyチームが、たまたま同時期に<a class="keyword" href="http://d.hatena.ne.jp/keyword/JIT">JIT</a>で<a class="keyword" href="http://d.hatena.ne.jp/keyword/Rails">Rails</a>高速化を達成したため、MJITを置き換えようとしている<a href="https://developers.redhat.com/blog/2021/04/27/the-mir-c-interpreter-and-just-in-time-jit-compiler">MIR</a>はもっと時間がかかりそうなこともあり、第一ステップとしてMJITはYJITに置き換えて(C<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%B3%A5%F3%A5%D1%A5%A4%A5%E9">コンパイラ</a>+dlopenを発破解体して)いこうという風になった。というか去年の末の時点ではShopifyチームがこの速度で成果を出してくるとは全く予想できなかったので、去年考えていた<a class="keyword" href="http://d.hatena.ne.jp/keyword/JIT">JIT</a>のロードマップとはかなり違う結末になったが、僕一人でメンテする状況ではなくなった上、MJITと違って極めて短いwarmupでRailsbenchで性能改善ができるようになったのはとても素晴らしいことだと思う。4月に最後の授業が終わったら時間に余裕ができるけど、YJITの発展が結構速くて春ごろの状況の予測が困難なので、今後どこに投資するかはその時になってから考えたいと思う。</p> <p>CRuby以外の点では、主に<a href="https://github.com/k0kubun/sqldef">sqldef</a>と<a href="https://github.com/k0kubun/rspec-openapi">rspec-openapi</a>、その他もいろいろ、で継続的にissueやPRが来るのでその対応などをやっていた。<a href="https://github.com/haml/haml/pull/1059">Haml 6をHamlitが乗っ取る</a>というのを作者にお願いされてそのパッチを書いてマージされたけどまだリリースされてないという活動もあった。今年、他の人がxremapをRustで書き直すという試みが2回行なわれたが、これは実は大分前から僕自身がやろうと温めていたア<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%A4%A5%C7%A5%A2">イデア</a>でもあったので、今月の期末テストが終わったタイミングからの時間を使って<a href="https://github.com/k0kubun/xremap">xremap</a>をRustに書き直すというのをやった。スターもまた伸びて嬉しい。</p> <p><a href="https://github.com/sponsors/k0kubun">GitHub Sponsors</a>で支援をいただいている方々には大変お世話になっております。<a class="keyword" href="http://d.hatena.ne.jp/keyword/OSS">OSS</a>は、仕事で給料が十分いただけてるのとは別腹というか、割と真面目に全てのissueやPRに対応している分、趣味とはいえど、僕がその時最も興味があるプロジェクトとは独立してそこそこメンテ作業にプライベート時間を割いているため、ここで少なからずお金をいただけているのは当初の想定を超えるほど精神的な支えになっています。特に、<a class="keyword" href="http://d.hatena.ne.jp/keyword/Comcast">Comcast</a>で1Gbpsのインターネットをする料金が月$100とバカ高い<a href="#f-e258346b" name="fn-e258346b" title="高い割には雨がちょっと降った程度で使えなくなるので意味がわからん">*12</a>のが経費になったり、生産性のためにマシンスペックを上げたりする時にこれも経費になったりするので、すごいケチな性格の僕としてはとても助かっています。</p> <h2>2021年は</h2> <p>今年は子供が寝てから朝5-6時まで宿題をやって提出して、朝7時に起きて子供と過ごすみたいな日が毎週ある感じだったけど、頭と腹は毎日痛くて、睡眠不足は寿命が縮まるしハゲるらしいので、来年は春学期でさっさとGPA 3.9<a href="#f-72d5d221" name="fn-72d5d221" title="もうBを1つ取って0.1削ったため">*13</a>で卒業して、その後は健康に過ごすことを目標にしたい。あとはこれ:</p> <p><blockquote data-conversation="none" class="twitter-tweet" data-lang="en"><p lang="und" dir="ltr"><a href="https://t.co/nrfHV1ZX9Z">pic.twitter.com/nrfHV1ZX9Z</a></p>&mdash; k0kubun (@k0kubun) <a href="https://twitter.com/k0kubun/status/1411140330175361031?ref_src=twsrc%5Etfw">July 3, 2021</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script> </p> <div class="footnote"> <p class="footnote"><a href="#fn-e83bfb5f" name="f-e83bfb5f" class="footnote-number">*1</a><span class="footnote-delimiter">:</span><span class="footnote-text">大学公認サークルである学園祭実行委員をやめただけで、それと同時に非公認の<a class="keyword" href="http://d.hatena.ne.jp/keyword/%C5%EC%B9%A9%C2%E7">東工大</a><a class="keyword" href="http://d.hatena.ne.jp/keyword/%B2%BB%A5%B2%A1%BC">音ゲー</a>サークルを立ち上げたので、勤務後や休日のゲーセン通いという名のサークル活動はやっていた</span></p> <p class="footnote"><a href="#fn-02a55de0" name="f-02a55de0" class="footnote-number">*2</a><span class="footnote-delimiter">:</span><span class="footnote-text">バイトの時は有給を取ってなかったので、社会人の時より普通に勤務時間が長かった。実際この時が一番本来の新卒ぽい成長をしていたし、新卒と会社が同じだったことを利用してこの期間がまるでフルタイムのように履歴書やLinkedInで書きがちなのはそのため。書かなかったとしても必要以上に実力を低く見つもられてお互い損するだけな気がする。</span></p> <p class="footnote"><a href="#fn-5d176605" name="f-5d176605" class="footnote-number">*3</a><span class="footnote-delimiter">:</span><span class="footnote-text">僕の給料を決める権限がある人にこういうのを読まれてしまうと交渉の立場が悪くなるのでこういうのはあまり書かない方が良いのだが、これを読んだとしてもフェアに決めてくれるだろうという信頼が既にある。</span></p> <p class="footnote"><a href="#fn-12b85c33" name="f-12b85c33" class="footnote-number">*4</a><span class="footnote-delimiter">:</span><span class="footnote-text">特にTD <a class="keyword" href="http://d.hatena.ne.jp/keyword/API">API</a>って奴は、3年前までに1年だけ在籍していたチームの<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%EA%A5%DD%A5%B8%A5%C8%A5%EA">リポジトリ</a>なんだけど、何故かそのチーム内にはこれまで僕よりコミットしている人がいなくて、在職者の中で過去に僕よりコミットしたのは古橋さんだけ、僕の次はもうやめたkamipoさん、という渋い状態になっている。僕が<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%EA%A5%D5%A5%A1%A5%E9">リファラ</a>ルしたmakimotoさんがそろそろkamipoさんを超えそうなので僕も抜いていって欲しい。</span></p> <p class="footnote"><a href="#fn-76392438" name="f-76392438" class="footnote-number">*5</a><span class="footnote-delimiter">:</span><span class="footnote-text">倍返しだ!! というのはおいといて、この辺をやる僕のチームのSeniorポジションが2月くらいに開くっぽいので、これを読んでる人どうですか? <a class="keyword" href="http://d.hatena.ne.jp/keyword/Rails">Rails</a>のコードを眺めたりちょっかいを出したりしながら、Kotlinでバックエンドの<a class="keyword" href="http://d.hatena.ne.jp/keyword/API">API</a>をバリバリ書きまくるみたいなのに興味があるルビーストがいたら是非<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%EA%A5%D5%A5%A1%A5%E9">リファラ</a>ルしたいのでDMしてください</span></p> <p class="footnote"><a href="#fn-2a135bc5" name="f-2a135bc5" class="footnote-number">*6</a><span class="footnote-delimiter">:</span><span class="footnote-text">予告通りAのボーダー90%はcurveしなかったが、roundはして89.5%以上がAとなったため</span></p> <p class="footnote"><a href="#fn-01d9e025" name="f-01d9e025" class="footnote-number">*7</a><span class="footnote-delimiter">:</span><span class="footnote-text"><a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%B3%A5%F3%A5%D1%A5%A4%A5%E9">コンパイラ</a>を書かない<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%B3%A5%F3%A5%D1%A5%A4%A5%E9">コンパイラ</a>の授業とは…? これで実際<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%B3%A5%F3%A5%D1%A5%A4%A5%E9">コンパイラ</a>書けるようになるのか…? と思ったものだが、今もその教科書は持っているので眺めてみたところ、全て<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%B3%A5%F3%A5%D1%A5%A4%A5%E9">コンパイラ</a>フロントエンドの理論の話で、これは今回の授業の3つのパートのうち1つ目でカバーされていた。実際、コードを書く授業かに関わらずもともとフロントエンド側には興味がなくてそこだけ知識が薄かったので、実際に(Aを取るために)真面目に勉強してみると勉強になった。それ以外のパートは、特に<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%EC%A5%B8%A5%B9%A5%BF">レジスタ</a>ー<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%A2%A5%ED%A5%B1%A1%BC%A5%B7%A5%E7%A5%F3">アロケーション</a>も何故か同じ教授の授業で全く同じレクチャー(完全にコピペだったので「[違うクラスの名前]にようこそ!」みたいな導入だった)を試聴済みだったのもあり、「知ってた」みたいな感じだった。</span></p> <p class="footnote"><a href="#fn-859bc51d" name="f-859bc51d" class="footnote-number">*8</a><span class="footnote-delimiter">:</span><span class="footnote-text">プログラミングについて「は」、というのが正しくて、数学とか物理とか文系科目がその他の時間を占めていたため。</span></p> <p class="footnote"><a href="#fn-9126e7fd" name="f-9126e7fd" class="footnote-number">*9</a><span class="footnote-delimiter">:</span><span class="footnote-text">まあBを取ってしまった<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%C7%A5%A3%A1%BC%A5%D7%A5%E9%A1%BC%A5%CB%A5%F3%A5%B0">ディープラーニング</a>に関してはもう何も言えませんが………</span></p> <p class="footnote"><a href="#fn-93fea1ec" name="f-93fea1ec" class="footnote-number">*10</a><span class="footnote-delimiter">:</span><span class="footnote-text">西日暮里で住んでた2DKの1.5倍くらい広い</span></p> <p class="footnote"><a href="#fn-5ff75cfb" name="f-5ff75cfb" class="footnote-number">*11</a><span class="footnote-delimiter">:</span><span class="footnote-text">型落ち<a class="keyword" href="http://d.hatena.ne.jp/keyword/DDR">DDR</a>とか<a class="keyword" href="http://d.hatena.ne.jp/keyword/IIDX">IIDX</a>じゃない<a class="keyword" href="http://d.hatena.ne.jp/keyword/beatmania">beatmania</a>は結構ある</span></p> <p class="footnote"><a href="#fn-e258346b" name="f-e258346b" class="footnote-number">*12</a><span class="footnote-delimiter">:</span><span class="footnote-text">高い割には雨がちょっと降った程度で使えなくなるので意味がわからん</span></p> <p class="footnote"><a href="#fn-72d5d221" name="f-72d5d221" class="footnote-number">*13</a><span class="footnote-delimiter">:</span><span class="footnote-text">もうBを1つ取って0.1削ったため</span></p> </div> k0kubun Linux用キーリマッパーxremapをRustで書き直した hatenablog://entry/13574176438045227401 2021-12-22T22:10:07+09:00 2021-12-23T09:50:05+09:00 このエントリはRust Advent Calendar (3) 22(-10)日目 の記事です。 5年前にxremapというLinux向けのキーリマッパーを作った (Linux向けの最強のキーリマッパーを作った - k0kubun's blog) のだが、X11のレイヤーで実装したため、GNOMEのActivitiesでリマップが効かなかったり、WaylandではXWayland内でしか動かないといった問題があった。 これらの問題を解決すべく、xkeysnailやwayremapといったツールが後に作られたのだが、xkeysnailはWaylandで動かずwayremapはX11で動かない方針… <p>このエントリは<a href="https://qiita.com/advent-calendar/2021/rust">Rust Advent Calendar (3)</a> 22(-10)日目 の記事です。</p> <p>5年前に<a href="https://github.com/k0kubun/xremap">xremap</a>という<a class="keyword" href="http://d.hatena.ne.jp/keyword/Linux">Linux</a>向けのキーリマッパーを作った (<a href="https://k0kubun.hatenablog.com/entry/xkremap">Linux&#x5411;&#x3051;&#x306E;&#x6700;&#x5F37;&#x306E;&#x30AD;&#x30FC;&#x30EA;&#x30DE;&#x30C3;&#x30D1;&#x30FC;&#x3092;&#x4F5C;&#x3063;&#x305F; - k0kubun&#39;s blog</a><a href="https://b.hatena.ne.jp/entry/https://k0kubun.hatenablog.com/entry/xkremap" class="http-bookmark"><img src="https://b.hatena.ne.jp/entry/image/https://k0kubun.hatenablog.com/entry/xkremap" alt="" class="http-bookmark" /></a>) のだが、<a class="keyword" href="http://d.hatena.ne.jp/keyword/X11">X11</a>のレイヤーで実装したため、<a class="keyword" href="http://d.hatena.ne.jp/keyword/GNOME">GNOME</a>のActivitiesでリマップが効かなかったり、WaylandではXWayland内でしか動かないといった問題があった。</p> <p>これらの問題を解決すべく、<a href="https://qiita.com/mooz@github/items/c5f25f27847333dd0b37">xkeysnail</a>や<a href="https://github.com/acro5piano/wayremap">wayremap</a>といったツールが後に作られたのだが、xkeysnailはWaylandで動かずwayremapは<a class="keyword" href="http://d.hatena.ne.jp/keyword/X11">X11</a>で動かない方針なのと、やはり全てのキー入力を中継するようなツールは<a class="keyword" href="http://d.hatena.ne.jp/keyword/Python">Python</a>のような遅い言語よりRustみたいな速い言語で書かれるべきだと思ったので、後発のツール<a href="#f-49b45bf7" name="fn-49b45bf7" title="xkeysnailやwayremapに加え、xremapをRustに書き直したrumap https://dawn.hateblo.jp/entry/rumap もその一つ">*1</a>の良いところ取りをしながら今回xremapを作り直した。</p> <p><iframe src="https://hatenablog-parts.com/embed?url=https%3A%2F%2Fgithub.com%2Fk0kubun%2Fxremap" title="GitHub - k0kubun/xremap: Dynamic key remapper for X Window System" class="embed-card embed-webcard" scrolling="no" frameborder="0" style="display: block; width: 100%; height: 155px; max-width: 500px; margin: 10px 0px;"></iframe><cite class="hatena-citation"><a href="https://github.com/k0kubun/xremap">github.com</a></cite></p> <h2>Rust版xremapの設計思想</h2> <h3><a class="keyword" href="http://d.hatena.ne.jp/keyword/JSON">JSON</a>互換な設定ファイル</h3> <p><a href="https://github.com/itamae-kitchen/mitamae/">mitamae</a>のように、宣言的な記述だけでなく<code>local_ruby_block</code>といった動的な処理をサポートすることを念頭に置いたツールもあるが、xremapに関してはほとんどが静的な設定で十分で、キーの入力以外に必要な処理もそこにごく少数の拡張をいれれば十分であると考えた。Rust版xremapの設定は、あるキー入力を別のキー入力にリマップする設定は以下のようにできるが、</p> <pre class="code lang-yaml" data-lang="yaml" data-unlink><span class="synIdentifier">keymap</span><span class="synSpecial">:</span> <span class="synStatement">- </span><span class="synIdentifier">name</span><span class="synSpecial">:</span> example <span class="synIdentifier">remap</span><span class="synSpecial">:</span> <span class="synIdentifier">M-c</span><span class="synSpecial">:</span> C-c </pre> <p>文字列をキー入力を表現する型として使いつつ、キーを1つだけ持つ<a class="keyword" href="http://d.hatena.ne.jp/keyword/%CF%A2%C1%DB%C7%DB%CE%F3">連想配列</a>を関数呼び出しのように使うと、ある程度リッチな機能も静的な設定で表現できる((注: この記事を書いている時点ではこの <code>launch</code> 関数は実装してないが、すぐに実装できるようにはしてあって、割とすぐ実装する予定))。</p> <pre class="code lang-yaml" data-lang="yaml" data-unlink><span class="synIdentifier">keymap</span><span class="synSpecial">:</span> <span class="synStatement">- </span><span class="synIdentifier">name</span><span class="synSpecial">:</span> example <span class="synIdentifier">remap</span><span class="synSpecial">:</span> <span class="synIdentifier">M-c</span><span class="synSpecial">:</span> <span class="synSpecial">{</span> <span class="synIdentifier">launch</span><span class="synSpecial">:</span> <span class="synConstant">'google-chrome'</span> <span class="synSpecial">}</span> </pre> <p>なお、<code>C-x C-s</code> のようなキーシーケンスをリマップする場合も、同じ仕組みで<code>remap</code>という関数を利用することで実現されている。</p> <pre class="code lang-yaml" data-lang="yaml" data-unlink>keymap <span class="synStatement">- </span><span class="synIdentifier">name</span><span class="synSpecial">:</span> example <span class="synIdentifier">remap</span><span class="synSpecial">:</span> <span class="synIdentifier">C-x</span><span class="synSpecial">:</span> <span class="synComment"> # 直後の入力でのみ以下のremapを適用</span> <span class="synIdentifier">remap</span><span class="synSpecial">:</span> <span class="synIdentifier">C-s</span><span class="synSpecial">:</span> C-w </pre> <p>そして、<a class="keyword" href="http://d.hatena.ne.jp/keyword/JSON">JSON</a>互換なことにより、<a class="keyword" href="http://d.hatena.ne.jp/keyword/Ruby">Ruby</a>や<a class="keyword" href="http://d.hatena.ne.jp/keyword/Python">Python</a>のような言語内の<a class="keyword" href="http://d.hatena.ne.jp/keyword/DSL">DSL</a>から生成したオブジェクトをxremapの設定に<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%B7%A5%EA%A5%A2%A5%E9%A5%A4%A5%BA">シリアライズ</a>するといったことが極めて用意になり、好きな言語が設定に使えるようになる。他のツールは<a class="keyword" href="http://d.hatena.ne.jp/keyword/Python">Python</a>でしか設定できないけど、<a class="keyword" href="http://d.hatena.ne.jp/keyword/Ruby">Ruby</a>の方が好き、という人はいると思う。あと、<a class="keyword" href="http://d.hatena.ne.jp/keyword/Ruby">Ruby</a> <a class="keyword" href="http://d.hatena.ne.jp/keyword/DSL">DSL</a>を維持するためにmrubyを使い続けようとすると、mrubyのビルドシステムで苦労したり、Rust&lt;-><a class="keyword" href="http://d.hatena.ne.jp/keyword/Ruby">Ruby</a>間のブリッジを書かないといけないのが面倒そうだったので、設定を境界にツールを二分した方がメンテしやすそうだとも考えている。</p> <p>なお、PoCとして<a href="https://github.com/xremap/xremap-ruby">xremap-ruby</a>や<a href="https://github.com/xremap/xremap-python">xremap-python</a>を作っていて、前者はmruby版xremapの<a class="keyword" href="http://d.hatena.ne.jp/keyword/DSL">DSL</a>に近く、後者はxkeysnailの<a class="keyword" href="http://d.hatena.ne.jp/keyword/DSL">DSL</a>に近いように作った<a href="#f-f917c7bd" name="fn-f917c7bd" title="が、特にPythonの方はlambdaでのマッチングをJSONに変換するといったことは難しいので、完全互換という風には作っていない">*2</a>。ただ、一旦リリースしてしまいたかった都合、現時点では<a class="keyword" href="http://d.hatena.ne.jp/keyword/YAML">YAML</a>用のドキュメントが一番充実している状態なので、ひとまず<a class="keyword" href="http://d.hatena.ne.jp/keyword/YAML">YAML</a>で使い始めていただく方が楽かもしれない。</p> <h3>Wayland対応</h3> <p>Xlibからevdev+uinputベースの実装に切り替えたことで、基本的な機能はWaylandプラットフォームでも動くようになった。ここはxkeysnailやwayremapも同じ。</p> <p>問題なのが、これらのツールは「現在フォーカスしているウィンドウ」に応じてリマップする機能を提供していることで、これをポータブルにするのが難しい。Waylandは<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%D7%A5%ED%A5%C8%A5%B3%A5%EB">プロトコル</a>内に「現在フォーカスしているウィンドウ」という概念がないようで、これをWaylandで動くコンポーザ全てでポータブルに判定するというのがどうも難しいらしい。Swayが使っているwlrootsという<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%D5%A5%EC%A1%BC%A5%E0%A5%EF%A1%BC%A5%AF">フレームワーク</a>を使っているコンポーザは多くあり、wlrootsの<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%D7%A5%ED%A5%C8%A5%B3%A5%EB">プロトコル</a>を話すとそれらのコンポーザには対応できるのだが、<a class="keyword" href="http://d.hatena.ne.jp/keyword/GNOME">GNOME</a>とかはwlrootsを使っていないので、2021年現在ではそれらに個別対応していく必要がありそう。</p> <p>で、特に<a class="keyword" href="http://d.hatena.ne.jp/keyword/GNOME">GNOME</a> Waylandはxkeysnailもwayremapも対応してないようなので、それらとの差別化として、xremapは<a class="keyword" href="http://d.hatena.ne.jp/keyword/GNOME">GNOME</a> Waylandの個別対応をいれた。<a class="keyword" href="http://d.hatena.ne.jp/keyword/GNOME">GNOME</a>特有の<a class="keyword" href="http://d.hatena.ne.jp/keyword/JavaScript">JavaScript</a>を<a class="keyword" href="http://d.hatena.ne.jp/keyword/D-Bus">D-Bus</a>に流し込むという奴なんだけど…まあ一切ポータブルじゃないのでその辺のツールがこれに対応してなくても文句いえなさそう。あと、<a class="keyword" href="http://d.hatena.ne.jp/keyword/GNOME">GNOME</a> 41以降では更に違う対応をしないといけないらしい。とりあえず<a class="keyword" href="http://d.hatena.ne.jp/keyword/Ubuntu">Ubuntu</a> 20.04で使われている<a class="keyword" href="http://d.hatena.ne.jp/keyword/GNOME">GNOME</a> 3.36では動くようにしてある。</p> <p>wayremapはSway向けの個別対応が入っているのだけど、wayremap作者のacro5pianoさん向けに、同じ対応をxremapにも入れた。</p> <p>ちなみにこれらの個別対応は <code>--features</code> を使って別バイナリとして実装していて、これは何故かというと、libX11は静的リンクが困難ぽいので、動的リンクの依存が非<a class="keyword" href="http://d.hatena.ne.jp/keyword/X11">X11</a>向けバイナリには不要なようにするため。</p> <h2>Rustを使ってみた感想</h2> <p>実はRustは<a href="https://github.com/k0kubun/xraise">5年くらい前に使ってみた</a>ことがあるのだが、その時は今回ほど複雑なツールを作らなかったのでまともに入門したわけではなく、実際何も覚えてなかったので、今回初めてRustを学んだ状態に近い。せっかくなので、初学者のフレッシュな感想を書き残しておこうと思う。</p> <h3>難しすぎワロタ</h3> <p>参照以外の方法で値を読もうとするとmoveが発生して、それにより<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%B3%A5%F3%A5%D1%A5%A4%A5%EB">コンパイル</a>が通らなくなる場面には多々遭遇するが、かといって <code>clone()</code> や <code>copy()</code> で解決すると負けたような気持ちになるので、なるべく速そうなコードで<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%B3%A5%F3%A5%D1%A5%A4%A5%EB">コンパイル</a>を通すパズルに頭を悩ませる時間が長い。とはいえ、これは他の言語では単にコピーが無限に発生して遅かったりスレッドセーフではない方法で参照を共有したりみたいな方法で解決されているだけの問題に見えるので、ここをサボらないようにするにはどうすればいいか考えること自体は人間が考えるに値する本質的な作業という感じがする。</p> <p>しかし、これはかなりテクが必要な感じがしており、ある程度便利イディオムのようなものを吸収するまでは、実装しているアプリが解決しようとしている問題とはあまり関係ないところでかなり時間を消費させられる感じがある。例えば、&amp;mut selfなメソッドがあるstructでは、&amp;mut selfでmutableなborrowをしているせいでselfの他のフィールドをimmutable borrowすることができなくなる(と理解している)が、そもそもmutしないようなフィールドはそういうstructの外側で管理するようにすると、そのselfとは独立してimmutable borrowが(複数)可能になり、いろいろやりやすくなる、とか思ったけど、そういうプ<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%E9%A5%AF">ラク</a>ティスをあらかじめ知ってないと辿りつけない設計が必要だったりするように思う。</p> <p>特にlifetime parameterはなかなか他の言語でお目にかかれない概念なので難しくて、これを使いこなしている人たちは本当にすごいと思う。Goとかは仕様がとてもシンプルな分、ある程度期間をあけて触ってもすぐに理解できる良さがあるが、Rustは高度な言語機能で全てを解決する方に振り切れている感じがしており、Rustで何かを書いた後少し離れて少し忘れてしまった時のことが心配ではある。</p> <h3><a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%B3%A5%F3%A5%D1%A5%A4%A5%E9">コンパイラ</a>のエラーメッセージがよくできてる</h3> <p><a class="keyword" href="http://d.hatena.ne.jp/keyword/Ruby">Ruby</a> 3.1にも<a href="https://github.com/ruby/error_highlight">error_highlight</a>というエラー表示を見やすくする機能が入るが、Rustに関してはムーブセマンティクスとlifetime parameterがあちこちで干渉しあってる時にそれらの原因を可視化するというのが明らかに大変そうなのにちゃんと実装されている。lifetime parameterのエラーは<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%B3%A5%F3%A5%D1%A5%A4%A5%E9">コンパイラ</a>の指示に従っているだけで一旦<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%B3%A5%F3%A5%D1%A5%A4%A5%EB">コンパイル</a>が通るといったこともあった。まあちゃんと理解してないと次のステップでコンフリクトして詰みとかも普通にあったけど…。</p> <h3><a class="keyword" href="http://d.hatena.ne.jp/keyword/IDE">IDE</a>はあった方がいいけどやや不便</h3> <p>Kotlinを書き始めたころ、<a class="keyword" href="http://d.hatena.ne.jp/keyword/Vim">Vim</a>で快適にKotlinを書くための良い環境がなかったのでそこから<a class="keyword" href="http://d.hatena.ne.jp/keyword/IntelliJ">IntelliJ</a>を併用するようになったのだが、特に学び始めでよくわかってなかったり、importなどそもそも全てを手動で書くのが面倒な感じの言語では<a class="keyword" href="http://d.hatena.ne.jp/keyword/IDE">IDE</a>は便利だと思う。モジュールとかimportのやり方をまだ完璧には理解できてないのだが、他の言語とかでも使えるインポートの<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%AD%A1%BC%A5%D0%A5%A4%A5%F3%A5%C9">キーバインド</a>を叩くだけで勝手に適切なimportが挿入されるのは初学者には嬉しい。</p> <p>で、これはJetBrainsの<a class="keyword" href="http://d.hatena.ne.jp/keyword/IDE">IDE</a>特有の話なんだけど、JetBrains製エディタのRust<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%D7%A5%E9%A5%B0%A5%A4%A5%F3">プラグイン</a>は基本的な機能は揃ってるものの、Kotlinや<a class="keyword" href="http://d.hatena.ne.jp/keyword/Java">Java</a>のような<a class="keyword" href="http://d.hatena.ne.jp/keyword/IntelliJ">IntelliJ</a>の本命っぽい言語に比べるとややサポートが弱い感じがする。例えばunused importを<a class="keyword" href="http://d.hatena.ne.jp/keyword/IDE">IDE</a>が教えてくれなくて、<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%B3%A5%F3%A5%D1%A5%A4%A5%E9">コンパイラ</a>のwarningが<a class="keyword" href="http://d.hatena.ne.jp/keyword/IDE">IDE</a>上ではどの行のことなのか丁寧に追って消すみたいな作業が必要になる。とはいえ、<a class="keyword" href="http://d.hatena.ne.jp/keyword/IntelliJ">IntelliJ</a>の操作に慣れている点が便利なので、他に便利なRust開発環境が現れることよりもJetBrainsがRustに投資してくれることを祈るばかりである。</p> <h3><code>?</code> 便利</h3> <p>基本的に難しくて大変だし <code>;</code> 書くの面倒だなあという印象が強かったけど、Rustの<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%B7%A5%F3%A5%BF%A5%C3%A5%AF%A5%B9">シンタックス</a>で唯一感心したのが <code>?</code> で、これは例えばGoで以下のように書くよくある奴が、</p> <pre class="code lang-go" data-lang="go" data-unlink>foo, err := bar() <span class="synStatement">if</span> err != <span class="synStatement">nil</span> { <span class="synStatement">return</span> err } </pre> <p>以下のように短く書けるという奴。</p> <pre class="code lang-rust" data-lang="rust" data-unlink><span class="synStatement">let</span> foo <span class="synStatement">=</span> <span class="synIdentifier">bar</span>()<span class="synSpecial">?</span>; </pre> <p>僕はどちらかというとエラーバケツリレーよりは例外がある言語の方が基本的には好きなのだが、バケツリレーのための追加記述が <code>?</code> の1文字で済むというのはとても良いと思う。</p> <h2>まとめ</h2> <p>xremapお試しください。既に常用できているけど、まだ足したいと思ってる機能がいくつかあるので、現時点ではないけど欲しい機能などあればコメントをいただければ優先度を上げたりできるかもしれない。</p> <div class="footnote"> <p class="footnote"><a href="#fn-49b45bf7" name="f-49b45bf7" class="footnote-number">*1</a><span class="footnote-delimiter">:</span><span class="footnote-text">xkeysnailやwayremapに加え、xremapをRustに書き直したrumap <a href="https://dawn.hateblo.jp/entry/rumap">https://dawn.hateblo.jp/entry/rumap</a> もその一つ</span></p> <p class="footnote"><a href="#fn-f917c7bd" name="f-f917c7bd" class="footnote-number">*2</a><span class="footnote-delimiter">:</span><span class="footnote-text">が、特に<a class="keyword" href="http://d.hatena.ne.jp/keyword/Python">Python</a>の方はlambdaでのマッチングを<a class="keyword" href="http://d.hatena.ne.jp/keyword/JSON">JSON</a>に変換するといったことは難しいので、完全互換という風には作っていない</span></p> </div> k0kubun アメリカのビザ取得からグリーンカード申請まで hatenablog://entry/26006613796561998 2021-08-12T17:55:27+09:00 2021-08-15T09:47:44+09:00 先週、会社のサポートによりアメリカのグリーンカード申請の最後のステージの提出が終わり、それが処理されるのを待った後少し事務手続をこなすとグリーンカードがもらえる状態まで来た。アメリカ移住に興味があるけど大変そうと思ってる人や、どの程度学歴が求められるか不安な人の参考になるよう、忘れないうちに全体のプロセスについてざっとまとめておく。*1 Diversity Visa 移民多様化ビザ。まず一番敷居が低い申請方法として、Diversity Visa Lottery (DV Lottery)というのがある。これは申し込むと抽選で誰でもグリーンカードが当たるという奴で、私もビザで渡米する前に2回挑戦し… <p>先週、会社のサポートにより<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%A2%A5%E1%A5%EA">アメリ</a>カの<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%B0%A5%EA%A1%BC%A5%F3%A5%AB%A1%BC%A5%C9">グリーンカード</a>申請の最後のステージの提出が終わり、それが処理されるのを待った後少し事務手続をこなすと<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%B0%A5%EA%A1%BC%A5%F3%A5%AB%A1%BC%A5%C9">グリーンカード</a>がもらえる状態まで来た。<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%A2%A5%E1%A5%EA">アメリ</a>カ移住に興味があるけど大変そうと思ってる人や、どの程度学歴が求められるか不安な人の参考になるよう、忘れないうちに全体のプロセスについてざっとまとめておく。<a href="#f-8f6acce5" name="fn-8f6acce5" title="なお、基本的にはまだ何も知らない人向けにゆるめに書いた文章であるため、実際に申請をする人は詳細は必ず移民弁護士に確認を取ること。">*1</a></p> <h1>Diversity Visa</h1> <p>移民多様化ビザ。まず一番敷居が低い申請方法として、<a href="https://dvprogram.state.gov/">Diversity Visa Lottery (DV Lottery)</a>というのがある。これは申し込むと抽選で誰でも<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%B0%A5%EA%A1%BC%A5%F3%A5%AB%A1%BC%A5%C9">グリーンカード</a>が当たるという奴で、私もビザで渡米する前に2回挑戦し、両方外した。</p> <h2>申請条件</h2> <p>以下の2つを満たす必要がある。(<a href="https://travel.state.gov/content/dam/visas/Diversity-Visa/DV-Instructions-Translations/DV-2022-Instructions-Translations/DV-2022-Instructions-and-FAQs_English.pdf">詳細</a>)</p> <ol> <li>出生国が<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%A2%A5%E1%A5%EA">アメリ</a>カへの移民率が低い国であること (日本はok)</li> <li>高校卒業か、最低2年の研修や経験が必要な仕事を2年経験していること</li> </ol> <p>これを読めている多くの人は申請資格を有しているのではないかと思う。会社に<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%A2%A5%E1%A5%EA">アメリ</a>カビザをサポートしてもらえる状況にはない人も、これに申し込んで祈ることはできる。</p> <h2>所要時間</h2> <p>10月上旬から11月上旬の間にインターネットで申し込みが完結し、結果は翌年5月上旬から9月末にかけてわかる。 用意する書類の中で面倒なのはせいぜい写真くらいしかない。写真の条件はやや厳しいので、<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%A2%A5%E1%A5%EA">アメリ</a>カビザ用写真に対応しているカメラ屋さんに行って写真を撮ってもらって電子データをもらっていた。会社でまともにビザと<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%B0%A5%EA%A1%BC%A5%F3%A5%AB%A1%BC%A5%C9">グリーンカード</a>を申請するのに比べるとすごく手間が少ない印象がある。</p> <h2>当選確率</h2> <p>DV-2021は<a href="https://travel.state.gov/content/dam/visas/Diversity-Visa/DVStatistics/DV-applicant-entrants-by-country-2019-2021.pdf">全世界で11,830,707人、日本は30,565人</a>の申し込みで、<a href="https://www.usgreencardoffice.com/winners/DV-2021">全世界で132,404人、日本は532人</a>当選したので、当選確率は <strong>全世界で1.1%、日本は1.7%</strong> といった感じ。10回申し込んで一度も当たらなかった同僚もいたりする反面、<a href="https://rebuild.fm/239/#t=1:23:20">実際当たってる人</a>もインターネットでは見かける。</p> <h1>Non-immigrant Visa</h1> <p>非移民ビザ。DV Lotteryを当てる強運を持っていない限り、最初に<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%A2%A5%E1%A5%EA">アメリ</a>カに移住する時普通はこれを取得することになる。全て挙げると<a href="https://travel.state.gov/content/travel/en/us-visas/visa-information-resources/all-visa-categories.html">たくさんある</a>のだが、ソフトウェアエンジニアが使ってると聞くようなものは限られてるので、それらについてまとめる。</p> <h2>H-1B</h2> <p><a class="keyword" href="http://d.hatena.ne.jp/keyword/%BD%A2%CF%AB%A5%D3%A5%B6">就労ビザ</a>。転職が可能であるため人気のビザ。ただ、抽選が必要で、必ずしも取れるわけじゃないのが特徴。3年間有効で、3年延長できるので、計6年使えることになる。</p> <h3>申請条件</h3> <p>専門性の証明のために学歴か職歴が必要になる。ソフトウェアエンジニアの場合は、</p> <ul> <li>日本でCS学士以上か、何らかの学士+6年以上の職歴: 通常枠</li> <li><a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%A2%A5%E1%A5%EA">アメリ</a>カでCS<a class="keyword" href="http://d.hatena.ne.jp/keyword/%BD%A4%BB%CE">修士</a>以上: Advanced Degree枠</li> </ul> <h3>所要時間</h3> <p>H-1Bは4/1から申し込みができ、抽選結果は5月くらいに出る。6月に会社が追加でお金を出すとPremium Processingができ、面接の後7月ころ審査結果が出て、9月末から10月頭くらいに入国できるのが最速。</p> <p>ただ、移民に厳しいトランプ政権下では進みが遅い年があって、2018年の人が翌年4月の入国になったり、そこで米国企業から反対が上がって2019年の人は10月に入国できたりしたが、2020年はコロナもあって発給停止になったりしていた。バイデン政権下ではそのようなことは少ないと思うが、進みの速さは運の要素が強そう。</p> <h3>当選確率</h3> <p>通常枠の抽選は一般に3分の1 (33%) の確率で当たると言われており、外れた場合も、Advanced Degreeにあたる場合は再抽選で少し確率が上がる (<a href="https://medium.com/@sakamoto.kazuki/2017-12-demystifying-us-visa-f596529701a3">トータル45%</a>程度)。</p> <h2>L-1B</h2> <p>転職できないが、抽選に依存しないビザ。H-1Bに落ちた場合に備えて、H-1Bと一緒に申し込みの準備を進めてくれる会社もある。3年間有効で、2年延長できるので、計5年間使える。従業員が1000人いるなどの条件を満たす大きめの会社は<a class="keyword" href="http://d.hatena.ne.jp/keyword/L-1">L-1</a> Visa Blanket Petitionというのを使うことができ、これがあると速やかな移住が可能になるらしい。そのくらいのサイズの会社に買収されると、ある日突然そういうのが使えるようになったりする。</p> <h3>申請条件</h3> <p>その会社の米国外拠点で1年以上働いていることが必要。</p> <h2>E-2</h2> <p>投資家ビザ。5年間有効。Eビザを発行するためには、ビザを発給される人と同じ国籍の <a href="#f-e410dfff" name="fn-e410dfff" title="この縛りがあることは @yusk_ さんにご共有いただきました https://twitter.com/yusk_/status/1426262331684626434">*2</a> 、米国永住権を持たない人たちがその会社を所有している必要がある。つまり、自分が日本人である場合、会社の株式の半数以上をまだ<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%B0%A5%EA%A1%BC%A5%F3%A5%AB%A1%BC%A5%C9">グリーンカード</a>を持たない日本人だけで<a class="keyword" href="http://d.hatena.ne.jp/keyword/%CA%DD%CD%AD">保有</a>していればこれが使える。やや厳しい条件だが、H-1Bのかわりにこれが使われるのを見たことがないでもない。</p> <h3>申請条件</h3> <p>管理職、役員、あるいは専門知識や技能の持ち主であることが必要。</p> <h2>O-1</h2> <p>アーティストビザ。<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%D7%A5%ED%A5%B9%A5%DD%A1%BC%A5%C4">プロスポーツ</a>選手とか<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%CE%A1%BC%A5%D9%A5%EB%BE%DE">ノーベル賞</a>取ったみたいなすごい人が使う奴。自分はソフトウェアエンジニアでいうところの<a class="keyword" href="http://d.hatena.ne.jp/keyword/%C2%E7%C3%AB%E6%C6%CA%BF">大谷翔平</a>だくらい自信がある人が取るのだと思うが、僕は学歴が学士卒<a href="#f-32470ef1" name="fn-32470ef1" title="いまでこそアメリカのCS修士に在学中だが、卒業はしていないので今でも使えなさそう">*3</a>であることからも最初から諦めていた。</p> <h3>申請条件</h3> <p>卓越した能力の保持者であることを証明する書類を提出する必要がある。海外で著名な人から推薦状をもらったみたいな話を聞く。基本的にはPhDを持ってる人が通してるイメージで、CS<a class="keyword" href="http://d.hatena.ne.jp/keyword/%BD%A4%BB%CE">修士</a>で通してる人もたまに見る。</p> <h2>F-1</h2> <p>学生ビザ。<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%A2%A5%E1%A5%EA">アメリ</a>カの大学を卒業後 OPT (Optional Practical Training) を使うと1年間働くことができ、その間に別のビザにスイッチするといった使われ方をするらしい。</p> <h1>Immigrant Visa</h1> <p>移民ビザ。永住権、<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%B0%A5%EA%A1%BC%A5%F3%A5%AB%A1%BC%A5%C9">グリーンカード</a>のこと<a href="#f-701b786c" name="fn-701b786c" title="厳密にはDiversity Visaも当然ながらこのカテゴリに入る気がするが、記事の流れの都合上この構成になってしまった上にいい感じの見出しが思いつかなかったのはご容赦いただきたい。">*4</a>。通常は大きくわけて3ステージあり、PERM、I-140、I-485 (AOS) に分けられ、これらを終えると晴れて<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%B0%A5%EA%A1%BC%A5%F3%A5%AB%A1%BC%A5%C9">グリーンカード</a>取得となる。なお、これらを全て終えるには大体2-3年 <a href="#f-89a0a5c2" name="fn-89a0a5c2" title="EB-2およびEB-3を想定している。なお、現在はいくつかの国は申請キューが分かれており日本は比較的処理が速くてこれなのだが、今後それが撤廃されてもう少し遅くなるリスクがあることに注意されたい https://redbus2us.com/hr1044-bill-passed-in-senate-summary/ 。ただ、通った後一気になくなるわけではなく、徐々に適用割合が増えていく感じぽいので、まだ申請してない人がめちゃくちゃ急ぐ必要があるわけでもなさそう。">*5</a> かかり、かつ転職や職務変更などで振り出しに戻ることがあることを考えると、普通はビザ取得直後に<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%B0%A5%EA%A1%BC%A5%F3%A5%AB%A1%BC%A5%C9">グリーンカード</a>申請の準備を始めるのが望ましいと思われる。</p> <h2>申請カテゴリ</h2> <p>申請者のレベルが高い順にEB-1、EB-2、EB-3 ... といった申請カテゴリがあり、EB-1だとPERMは不要になり、一般にプロセスが速くなる。</p> <ul> <li>EB-1: O-1を取るような技能があったり、国際企業の管理職であったりすると該当</li> <li>EB-2: <a class="keyword" href="http://d.hatena.ne.jp/keyword/%BD%A4%BB%CE">修士</a>以上の学歴か、学士と5年以上の職歴で該当</li> <li>EB-3: 学士以上の学歴が必要</li> </ul> <p>私は申請を始めた時点で5年の職歴があったけど、書類を作り始めた時点ではギリギリ足りなかったので、EB-3になった。ただ、EB-2とEB-3は独立したキューであって、どちらも処理が詰まっていない (<a href="https://travel.state.gov/content/travel/en/legal/visa-law0/visa-bulletin.html">Visa Bulletin</a>に C = Current が書いてある) 限りはどちらでも速度が変わらない。</p> <h2>PERM</h2> <p>書類の準備が一番面倒くさいステージ。過去に所属していた会社から職歴を証明してもらう書類を集めたりする必要がある。大学の教授に推薦状をもらうといったことをやっていた人も見た <a href="#f-4f7e09db" name="fn-4f7e09db" title="私は移民弁護士が大学のレベルのようなものを審査する機関から書類を取り寄せていて、それと私のdiplomaとtranscriptがセットで必要書類が揃った感じになっており、私はこれはやらなかった">*6</a>。</p> <p>書類を集めたあと、申請者の職務を記載したjob postingをして一定期間放置し、<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%A2%A5%E1%A5%EA">アメリ</a>カには該当する技能を持つ人がいないことを証明する必要があり、それに必要な書類を要求して送られてくるまでの期間も含めるとこれに結構時間がかかる。一方、<a class="keyword" href="http://d.hatena.ne.jp/keyword/Google">Google</a>のような年中<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%B0%A5%EA%A1%BC%A5%F3%A5%AB%A1%BC%A5%C9">グリーンカード</a>申請をしている会社ではなんかそれっぽいjob postingをプールしていて、<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%B0%A5%EA%A1%BC%A5%F3%A5%AB%A1%BC%A5%C9">グリーンカード</a>申請者はその後のステップから開始できるという話も聞いた。</p> <p>なお、PERMは職種に紐付くものであるため、転職するとやり直しで、転職しなくても職務内容が大きく変わった場合やり直しになる。</p> <h3>所要時間</h3> <p>PERMを提出できてから承認されるまでは通常4-6か月かかる。その提出に必要な書類の準備が順調に進めても半年くらいかかるので、実際には1年くらいここで使うことになる。</p> <h2>I-140</h2> <p>これは雇用主の審査で、企業が規定の給料を払う経済的能力があるかどうかが審査される。書類を書いて出して処理されるのを待つ以外のことはあまりない模様。なお、I-140と次のI-485は並行して進めることができる <a href="#f-0713bcd1" name="fn-0713bcd1" title="同時申請にはリスクもあり、特にdual intent visaでない場合は、非移民ビザがI-485を出した瞬間原則失効するので避けた方が良いと @Yuryu さんにご共有いただきました https://twitter.com/Yuryu/status/1426279993122844674">*7</a> 。</p> <h3>所要時間</h3> <p><a href="https://egov.uscis.gov/processing-times/">ここ</a>で見れるが、私のケースでは7.5-8か月程度かかる見込み。</p> <h2>I-485 (Adjustment of Status)</h2> <p>最終ステージ。実際の<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%B0%A5%EA%A1%BC%A5%F3%A5%AB%A1%BC%A5%C9">グリーンカード</a>申請にあたる。戸籍抄本を日本から取り寄せたり、両親の出生地や生年月日や現住所を調べたりする必要がある。健康診断の結果を提出する必要があるのもここだが、処理を待つ間に失効してしまうので、申請時点では健康診断の結果は準備しない。あと指紋採取をしたりするらしい。なお、AOS (Adjustment of Status) は米国内で申請を行なう場合に使うやつで、在外米国大使館で面接を受けるConsular Processingというやり方もあるらしい。</p> <h3>所要時間</h3> <p>11-23か月程度かかる見込み。これが<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%DC%A5%C8%A5%EB%A5%CD%A5%C3%A5%AF">ボトルネック</a>ぽい。</p> <h2>その他</h2> <p><a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%B0%A5%EA%A1%BC%A5%F3%A5%AB%A1%BC%A5%C9">グリーンカード</a>取得に必ずしも必要なわけではないが、普通PERMの次のステージでI-140やI-485 (AOS) と同時に申し込まれるForm 2つを紹介する。</p> <h3>I-131: Advance Parole</h3> <p><a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%B0%A5%EA%A1%BC%A5%F3%A5%AB%A1%BC%A5%C9">グリーンカード</a>申請中は<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%A2%A5%E1%A5%EA">アメリ</a>カを出国できないみたいな話を見かけることがあるが、これがそれにあたる。実際には、H-1B、L-1BなどのDual Intent Visaと呼ばれるものを持っている場合は<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%B0%A5%EA%A1%BC%A5%F3%A5%AB%A1%BC%A5%C9">グリーンカード</a>申請中も出国・再入国できるのだが、このAdvance Paroleはそういったビザが失効しても<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%B0%A5%EA%A1%BC%A5%F3%A5%AB%A1%BC%A5%C9">グリーンカード</a>申請中は再入国できるように申請するもの。なのであくまで保険なのだが、これをI-140やI-485と一緒に出した後承認される前に出国してしまうとAdvance Paroleの申請は無効になり、ややリスクが上がる。そのためこのステージにいる間は<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%A2%A5%E1%A5%EA">アメリ</a>カを出国せず過ごすのが望ましい。</p> <h4>所要時間</h4> <p>4.5-6.5か月程度かかる見込み。半年くらい海外出張や一時帰国をしない前提になりそう。</p> <h3>I-765: Employment Authorization</h3> <p>これもAdvance Paroleに似た保険にあたる奴で、<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%B0%A5%EA%A1%BC%A5%F3%A5%AB%A1%BC%A5%C9">グリーンカード</a>申請中に働く許可を得るためのもの。</p> <h4>所要時間</h4> <p>1.5-6.5か月程度かかる見込み。</p> <h1>弊社について</h1> <p>私がビザや<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%B0%A5%EA%A1%BC%A5%F3%A5%AB%A1%BC%A5%C9">グリーンカード</a>の申請をスムーズにできるよう移民弁護士のサポートを受けられているのは全面的に会社のおかげなので、弊社の宣伝をしたい。We're hiring! 面白い仕事がいっぱいある上に金銭的待遇が良いだけでなく、ビザのサポートも手厚い会社だと思う<a href="#f-da528e19" name="fn-da528e19" title="念のため書いておくと、入社していきなり移住というケースは少なくて、入社後に実績が認められ、移住することで会社側に何らかのメリットがある人が移住するということが多い。参考までに、僕は入社直後から移住したいと伝えていた結果、入社2年後にビザの手続が始められた。">*8</a>。<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%A2%A5%E1%A5%EA">アメリ</a>カだけでなく、日本からカナダへの移住をした同僚も複数いる。</p> <p><a href="https://www.treasuredata.com/company/careers/jobs/?team=Engineering">Jobs - Treasure Data</a></p> <h1>参考記事</h1> <p>僕が申請前にお世話になったり、申請後見かけたりした関連記事の中でパッと思い出したものを載せておく。</p> <ul> <li><a href="https://medium.com/@sakamoto.kazuki/2017-12-demystifying-us-visa-f596529701a3">ソフトウェアエンジニアのUSビザ</a></li> <li><a href="https://fushiroyama.hatenablog.com/entry/2021/01/29/063144">アメリカでソフトウェアエンジニアになりたい皆さんへ</a></li> <li><a href="https://blog.keikooda.net/2017/11/04/how-i-got-my-greencard/">How I Got My Green Card</a></li> <li><a href="https://seattle-life.hatenablog.com/entry/2021/02/05/132244">パンデミック中のグリーンカード取得体験記</a></li> </ul> <div class="footnote"> <p class="footnote"><a href="#fn-8f6acce5" name="f-8f6acce5" class="footnote-number">*1</a><span class="footnote-delimiter">:</span><span class="footnote-text">なお、基本的にはまだ何も知らない人向けにゆるめに書いた文章であるため、実際に申請をする人は詳細は必ず移民弁護士に確認を取ること。</span></p> <p class="footnote"><a href="#fn-e410dfff" name="f-e410dfff" class="footnote-number">*2</a><span class="footnote-delimiter">:</span><span class="footnote-text">この縛りがあることは @yusk_ さんにご共有いただきました <a href="https://twitter.com/yusk_/status/1426262331684626434">https://twitter.com/yusk_/status/1426262331684626434</a></span></p> <p class="footnote"><a href="#fn-32470ef1" name="f-32470ef1" class="footnote-number">*3</a><span class="footnote-delimiter">:</span><span class="footnote-text">いまでこそ<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%A2%A5%E1%A5%EA">アメリ</a>カのCS<a class="keyword" href="http://d.hatena.ne.jp/keyword/%BD%A4%BB%CE">修士</a>に在学中だが、卒業はしていないので今でも使えなさそう</span></p> <p class="footnote"><a href="#fn-701b786c" name="f-701b786c" class="footnote-number">*4</a><span class="footnote-delimiter">:</span><span class="footnote-text">厳密にはDiversity Visaも当然ながらこのカテゴリに入る気がするが、記事の流れの都合上この構成になってしまった上にいい感じの見出しが思いつかなかったのはご容赦いただきたい。</span></p> <p class="footnote"><a href="#fn-89a0a5c2" name="f-89a0a5c2" class="footnote-number">*5</a><span class="footnote-delimiter">:</span><span class="footnote-text">EB-2およびEB-3を想定している。なお、現在はいくつかの国は申請キューが分かれており日本は比較的処理が速くてこれなのだが、今後それが撤廃されてもう少し遅くなるリスクがあることに注意されたい <a href="https://redbus2us.com/hr1044-bill-passed-in-senate-summary/">https://redbus2us.com/hr1044-bill-passed-in-senate-summary/</a> 。ただ、通った後一気になくなるわけではなく、徐々に適用割合が増えていく感じぽいので、まだ申請してない人がめちゃくちゃ急ぐ必要があるわけでもなさそう。</span></p> <p class="footnote"><a href="#fn-4f7e09db" name="f-4f7e09db" class="footnote-number">*6</a><span class="footnote-delimiter">:</span><span class="footnote-text">私は移民弁護士が大学のレベルのようなものを審査する機関から書類を取り寄せていて、それと私のdiplomaとtranscriptがセットで必要書類が揃った感じになっており、私はこれはやらなかった</span></p> <p class="footnote"><a href="#fn-0713bcd1" name="f-0713bcd1" class="footnote-number">*7</a><span class="footnote-delimiter">:</span><span class="footnote-text">同時申請にはリスクもあり、特にdual intent visaでない場合は、非移民ビザがI-485を出した瞬間原則失効するので避けた方が良いと @Yuryu さんにご共有いただきました <a href="https://twitter.com/Yuryu/status/1426279993122844674">https://twitter.com/Yuryu/status/1426279993122844674</a></span></p> <p class="footnote"><a href="#fn-da528e19" name="f-da528e19" class="footnote-number">*8</a><span class="footnote-delimiter">:</span><span class="footnote-text">念のため書いておくと、入社していきなり移住というケースは少なくて、入社後に実績が認められ、移住することで会社側に何らかのメリットがある人が移住するということが多い。参考までに、僕は入社直後から移住したいと伝えていた結果、入社2年後にビザの手続が始められた。</span></p> </div> k0kubun おうちで食べる二郎系ラーメン hatenablog://entry/26006613726237121 2021-05-09T08:37:23+09:00 2021-05-09T08:38:30+09:00 コロナでラーメン屋が減った コロナが始まったころ、近所では飲食店がテイクアウトしかできなくなり、好きだったみそラーメン屋や近所で唯一二郎系ラーメンを出していた店はその間に閉店してしまった。 ふと二郎系ラーメンを食べたい気持ちになったが、自宅からその次にくらい近い二郎系ラーメンを出す店は飛行機で行くような場所にあるし、デリバリーで自分の家まで二郎系ラーメンが届くサービスもどうやらなさそうなので、自分で作ることにした。 よくある本格二郎系ラーメンレシピ ちゃんとした味を再現しようとすると、以下のように、ゲンコツや背脂みたいなやや調達が面倒そうな材料を用意して、スープだけで最低2時間半かけて作る感じ… <h1>コロナでラーメン屋が減った</h1> <p>コロナが始まったころ、近所では飲食店がテイクアウトしかできなくなり、<a href="https://www.yelp.com/biz/misoya-santa-clara-2">好きだったみそラーメン屋</a>や<a href="https://www.yelp.com/biz/shalala-mountain-view-2">近所で唯一二郎系ラーメンを出していた店</a>はその間に閉店してしまった。</p> <p>ふと二郎系ラーメンを食べたい気持ちになったが、自宅からその次にくらい近い<a href="https://www.yelp.com/biz/tsujita-la-artisan-noodle-annex-los-angeles-3">二郎系ラーメンを出す店</a>は飛行機で行くような場所にあるし、デリバリーで自分の家まで二郎系ラーメンが届くサービスもどうやらなさそうなので、自分で作ることにした。</p> <h1>よくある本格二郎系ラーメンレシピ</h1> <p>ちゃんとした味を再現しようとすると、以下のように、ゲンコツや背脂みたいなやや調達が面倒そうな材料を用意して、スープだけで最低2時間半かけて作る感じのレシピが出てくる。 <a href="#f-8b00950c" name="fn-8b00950c" title="あとで https://cookpad.com/recipe/6254137 というレシピも見つけた。これはスープの材料的には楽そう。">*1</a></p> <p><a target="_blank" href="https://cookpad.com"><img style="border: 0px; vertical-align: middle;" src="https://img3.cookpad.com/image/link/cpicon.gif" alt="Cpicon" /></a> <a style="color:#7d940a;font-weight:600;" target="_blank" href="https://cookpad.com/recipe/5031573">ラーメン二郎 (乳化) 完全再現 by ★メタボのレシピ★</a></p> <p>これはちょっとやってられないので、とりあえず手抜きで作ることにした。</p> <h1>手抜き二郎</h1> <p>角煮を作ったときに、煮汁の醤油と脂っぽさがなんか二郎っぽいな、と思ったことがあったので、角煮を作ったときにその汁と市販の濃厚豚骨スープを融合させ、醤油を足してカラメにし、二郎っぽいトッピングを使ったところ割りとそれっぽい感じになった。</p> <p><blockquote data-conversation="none" class="twitter-tweet" data-lang="en"><p lang="und" dir="ltr">👨‍🍳🍜 <a href="https://t.co/4yJ09kAZNQ">pic.twitter.com/4yJ09kAZNQ</a></p>&mdash; k0kubun (@k0kubun) <a href="https://twitter.com/k0kubun/status/1389036132243963904?ref_src=twsrc%5Etfw">May 3, 2021</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script> </p> <p>角煮を普通に作ってこのパックを用意するだけで面倒なパートが大体終わるので、これの<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%B3%A5%B9%A5%D1">コスパ</a>は結構よかった。自作二郎のいいところは、もやしとキャベツとにんにくと醤油が味の大部分を占めていて、それらの準備で失敗することはまずない上に、この辺りをマシマシにしておけば結構味がキマるため、料理がヘタクソでも高い確率で二郎っぽくなるところかなと思う。</p> <p>でも、この市販スープも麺もあんまり二郎っぽくない (かといってそれより二郎ぽいのもない) ので、麺とスープは調達方法変えてもいいなと思ったのだった。</p> <h1>ろたすさんの家二郎レシピ</h1> <p>ラーメンろたすという店をやっている ge-c さんが<a href="https://www.youtube.com/watch?v=r9m4tlCvfm0">YouTube</a>で家で作れる二郎系ラーメンの作り方を紹介している。ge-c さんの <a target="_blank" href="https://www.amazon.co.jp/gp/product/B08TWVNKX9/ref=as_li_tl?ie=UTF8&camp=247&creative=1211&creativeASIN=B08TWVNKX9&linkCode=as2&tag=k0kubun05-22&linkId=c363d27e28d4d3609eea579d08c36a96">極上のおうちラーメン</a> という本にも、家二郎という章にレシピがまとまっている。</p> <iframe style="width:120px;height:240px;" marginwidth="0" marginheight="0" scrolling="no" frameborder="0" src="https://rcm-fe.amazon-adsystem.com/e/cm?ref=tf_til&t=k0kubun05-22&m=amazon&o=9&p=8&l=as1&IS1=1&detail=1&asins=B08TWVNKX9&linkId=0ae4c2aef36684aa0d34ae57bfc646fe&bc1=ffffff&amp;lt1=_top&fc1=333333&lc1=0066c0&bg1=ffffff&f=ifr"> </iframe> <p>本の家二郎の章の写真は割りと本格的に見えるのに、<a class="keyword" href="http://d.hatena.ne.jp/keyword/YouTube">YouTube</a>のレシピより材料の調達が簡単かつスープが1時間ちょっとで完成するところに惹かれ、今回それを作ってみた。</p> <p><blockquote data-conversation="none" class="twitter-tweet" data-lang="en"><p lang="und" dir="ltr">🍜 <a href="https://t.co/yyLyVlToDb">pic.twitter.com/yyLyVlToDb</a></p>&mdash; k0kubun (@k0kubun) <a href="https://twitter.com/k0kubun/status/1391146535912493058?ref_src=twsrc%5Etfw">May 8, 2021</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script> </p> <p>前回の手抜きの奴より大分それっぽい味になった。レシピについては本や<a class="keyword" href="http://d.hatena.ne.jp/keyword/YouTube">YouTube</a>の方を見て欲しいが、特徴的な材料の調達に関する知見だけまとめておく。</p> <h2>麺</h2> <p>麺については、パスタ麺なのだが、<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%EA%A5%F3%A5%B0%A5%A4%A5%CD">リングイネ</a>や<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%D5%A5%A3%A5%C3%A5%C8%A5%C1%A1%BC%A5%CD">フィットチーネ</a>が推奨されている。僕は<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%EA%A5%F3%A5%B0%A5%A4%A5%CD">リングイネ</a>を試してみたが、ある程度太麺で、ほどほどに平たいので、たしかに市販パックのラーメンよりぽいなという感じがした。調達は簡単で、<a class="keyword" href="http://d.hatena.ne.jp/keyword/Amazon">Amazon</a>とかで結構ある。僕は乾麺を買ったけど生パスタの方がおいしいらしい。</p> <iframe style="width:120px;height:240px;" marginwidth="0" marginheight="0" scrolling="no" frameborder="0" src="https://rcm-fe.amazon-adsystem.com/e/cm?ref=tf_til&t=k0kubun05-22&m=amazon&o=9&p=8&l=as1&IS1=1&detail=1&asins=B079SYFWS5&linkId=9a916be33e135cf35b1a9355be8ffe30&bc1=ffffff&amp;lt1=_top&fc1=333333&lc1=0066c0&bg1=ffffff&f=ifr"> </iframe> <h2>豚バラ</h2> <p>豚バラ (Pork Belly) は普通の部位なのに何故か置いてなかったりとか (売り切れ?)、なんか皮つきで売られてたりとか、切られたサイズが結構小さめだったりとかして面倒くさい。僕の近所ではマルカイというスーパーで売ってる奴がちょうどいい。</p> <h2>豚足</h2> <p>豚足を買ったことがなかったが、中国系スーパーの99 Ranch Marketに行ったらおいてあった。でも足が3cmおきに切り込みが入った状態で売ってるので、ここで買うとどちらかというと豚骨を使うような感じになる気がする。</p> <h2>背脂</h2> <p>最難関。背脂は普通は破棄する部位なので売っておらず、基本的にはスーパーの肉カウンターか肉屋に行って、店の人に話しかけて出してもらうしかないらしい。僕の近所では、肉屋が全部<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%CF%A5%E9%A1%BC%A5%EB">ハラール</a>屋さんで、どこも豚肉だけはないのでスーパーを使うしかない状態だった。<a class="keyword" href="http://d.hatena.ne.jp/keyword/Safeway">Safeway</a>というスーパーで聞いてみたら、その時は置いてなかったけど、正午までに店に電話して聞いてくれれば用意しておくよと言われた。99 Ranch MarketでPork Fatどれ?って聞いて言われた奴を今回は使ったけど、それは何か背脂とは違うものだった感じがした。</p> <h1>次作るときは</h1> <p>次は手抜き二郎と家二郎レシピの中間くらいの感じにしてみようかなと思っている。特にチャーシューは圧力鍋でやった方がおいしくなるかなと思った。</p> <div class="footnote"> <p class="footnote"><a href="#fn-8b00950c" name="f-8b00950c" class="footnote-number">*1</a><span class="footnote-delimiter">:</span><span class="footnote-text">あとで <a href="https://cookpad.com/recipe/6254137">https://cookpad.com/recipe/6254137</a> というレシピも見つけた。これはスープの材料的には楽そう。</span></p> </div> k0kubun まだパソコンのOS選びで消耗してるの? hatenablog://entry/26006613722116089 2021-04-29T13:18:14+09:00 2021-04-29T13:18:35+09:00 昨日、大学生協推奨のPCが20万のWindowsマシンなのを見てなぜMacじゃないのかという声がTLに流れていたり、それで思い出したのか、逆にMacじゃなくてLinuxを使っている人はなぜそうしてるのかみたいな話がvim-jpで盛り上がったりしていた。 Windowsを使い始めてから17年、Macを使い始めてから8年、Linuxデスクトップを使い始めてから6年経ち、今は用途に応じてその3つをどれも使っているという感じなのだが、個人的にはどれも善し悪しだと思っているので、状況に応じて何を使うべきか自分の考えを書いておく。 大学生は何を買うべきか 特にプログラミングとかやるつもりがない大学生でお金… <p>昨日、<a class="keyword" href="http://d.hatena.ne.jp/keyword/%C2%E7%B3%D8%C0%B8%B6%A8">大学生協</a>推奨のPCが20万の<a class="keyword" href="http://d.hatena.ne.jp/keyword/Windows">Windows</a>マシンなのを見てなぜ<a class="keyword" href="http://d.hatena.ne.jp/keyword/Mac">Mac</a>じゃないのかという声がTLに流れていたり、それで思い出したのか、逆に<a class="keyword" href="http://d.hatena.ne.jp/keyword/Mac">Mac</a>じゃなくて<a class="keyword" href="http://d.hatena.ne.jp/keyword/Linux">Linux</a>を使っている人はなぜそうしてるのかみたいな話が<a class="keyword" href="http://d.hatena.ne.jp/keyword/vim">vim</a>-jpで盛り上がったりしていた。</p> <p><a class="keyword" href="http://d.hatena.ne.jp/keyword/Windows">Windows</a>を使い始めてから17年、<a class="keyword" href="http://d.hatena.ne.jp/keyword/Mac">Mac</a>を使い始めてから8年、<a class="keyword" href="http://d.hatena.ne.jp/keyword/Linux">Linux</a>デスクトップを使い始めてから6年経ち、今は用途に応じてその3つをどれも使っているという感じなのだが、個人的にはどれも善し悪しだと思っているので、状況に応じて何を使うべきか自分の考えを書いておく。</p> <h1>大学生は何を買うべきか</h1> <p>特にプログラミングとかやるつもりがない大学生でお金がある人は、素直に推奨された<a class="keyword" href="http://d.hatena.ne.jp/keyword/Windows">Windows</a>マシンを買っておくと、大学側が使わせてくるソフトが動かない可能性も流石に低いだろうし、周りと環境が揃っていて質問とかしやすいので無難だと思う。金がなければ中古で似たような奴を探したり、バイトなどすると良い。</p> <p>これからプログラミングを始めますという学生は、<a class="keyword" href="http://d.hatena.ne.jp/keyword/Mac">Mac</a> (中古のIntel MacBook Proか、M1の<a class="keyword" href="http://d.hatena.ne.jp/keyword/MacBook%20Pro">MacBook Pro</a>あたり) を買うのが良いと思う。理由は単純で、開発に使うものは<a class="keyword" href="http://d.hatena.ne.jp/keyword/Windows">Windows</a>じゃなくても大体動くし、逆に<a class="keyword" href="http://d.hatena.ne.jp/keyword/iOS">iOS</a>開発は突然やりたくなっても<a class="keyword" href="http://d.hatena.ne.jp/keyword/macOS">macOS</a>でしかできないため。あと、その辺のWeb系企業が社員に貸与するマシンは<a class="keyword" href="http://d.hatena.ne.jp/keyword/Mac">Mac</a>なことが多いので、そういう会社が視野の人は早いうちにそれでの開発に慣れておくと便利。</p> <h1>開発が趣味の人は何を使うべきか</h1> <p>仕事以外でもプログラミングするけど、別に開発環境にそんなに拘りがないという人は、普通に趣味でも会社と同じOSを使っておく方が業務中にハマる時間が短く済むのでそれが良いと思う。</p> <p>じゃあ、開発環境いじったり開発効率を向上したりする活動そのものが趣味ですみたいな人はどうか。そういう人は、きっとどれを選んでも大体楽しんでなんとかできるので、面白そうと思ったOSを全部試してみるのがおすすめ。そのうち自分のお気に入りが見つかると思う。</p> <p>まあこれだと何らかの理由で選択肢が複数ある人や、そもそもどれから試すべきか悩んでるステージの人には何の足しにもならないので、現時点での個人の感想を以下に書く。書いてない奴も、単に今思いついてないだけの可能性もあるけど、普通に知らない可能性もあるので何かあったら教えてほしい。特に<a class="keyword" href="http://d.hatena.ne.jp/keyword/Windows">Windows</a>は僕が勉強不足な可能性が高い。</p> <h1><a class="keyword" href="http://d.hatena.ne.jp/keyword/Windows">Windows</a></h1> <h2>良い所</h2> <ul> <li>ゲームを始めとして、<a class="keyword" href="http://d.hatena.ne.jp/keyword/Windows">Windows</a>にだけ対応してるアプリが結構ある</li> <li>優秀なキーリマッパー (例えばのどか <a href="#f-c0c1cd3c" name="fn-c0c1cd3c" title="窓使いの憂鬱の派生プロジェクト">*1</a> ) があり、<a class="keyword" href="http://d.hatena.ne.jp/keyword/Mac">Mac</a>っぽい<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%AD%A1%BC%A5%D0%A5%A4%A5%F3%A5%C9">キーバインド</a> <a href="#f-a94036d6" name="fn-a94036d6" title="CtrlでEmacsキーバインド、Ctrlじゃない修飾キーでコピーやペーストなど">*2</a> もある程度再現できる</li> <li>WSL2ができたので<a class="keyword" href="http://d.hatena.ne.jp/keyword/macOS">macOS</a>よりも<a class="keyword" href="http://d.hatena.ne.jp/keyword/Linux">Linux</a>寄りの環境が使いやすくなった</li> <li><a class="keyword" href="http://d.hatena.ne.jp/keyword/OSS">OSS</a>のWin32や<a class="keyword" href="http://d.hatena.ne.jp/keyword/MinGW">MinGW</a>対応をするときに便利</li> </ul> <h2>悪い所</h2> <ul> <li>ファイルパスの扱いの違いや、<a class="keyword" href="http://d.hatena.ne.jp/keyword/ANSI">ANSI</a><a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%A8%A5%B9">エス</a>ケープシーケンスや、ネイティブな<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%B7%A5%B9%A5%C6%A5%E0%A5%B3%A1%BC%A5%EB">システムコール</a>の違いにより、<a class="keyword" href="http://d.hatena.ne.jp/keyword/Windows">Windows</a>以外では大体スッと動くが<a class="keyword" href="http://d.hatena.ne.jp/keyword/Windows">Windows</a>対応には一手間かかる開発用ツールはそこそこあり、<a class="keyword" href="http://d.hatena.ne.jp/keyword/Windows">Windows</a>に対応してないか、mattnさんが<a class="keyword" href="http://d.hatena.ne.jp/keyword/Windows">Windows</a>対応したかみたいな状態になりがち。</li> <li>HiDPI (<a class="keyword" href="http://d.hatena.ne.jp/keyword/Mac">Mac</a>でいう<a class="keyword" href="http://d.hatena.ne.jp/keyword/Retina">Retina</a>) にOSレベルでは対応しているが、アプリ側が対応してないとそういうアプリだけ文字の解像度が低く汚ない感じになる。</li> </ul> <h1><a class="keyword" href="http://d.hatena.ne.jp/keyword/macOS">macOS</a></h1> <h2>良い所</h2> <ul> <li><a class="keyword" href="http://d.hatena.ne.jp/keyword/Retina">Retina</a>表示の対応率がすごい。ありとあらゆるアプリがほぼ常に綺麗に表示される。</li> <li>極めて便利なキーリマッパー (Karabiner-Elements) がある</li> <li><a class="keyword" href="http://d.hatena.ne.jp/keyword/Emacs">Emacs</a> <a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%AD%A1%BC%A5%D0%A5%A4%A5%F3%A5%C9">キーバインド</a>が標準で使え <a href="#f-89c5c0b3" name="fn-89c5c0b3" title="これ、ほとんどはWindowsやLinuxでも再現できるんだけど、じゃあ何が嬉しいかっていうと、例えばHomeやEndでC-aとC-eをエミュレートする時、論理行頭/末じゃなくて物理行頭/末になってしまうという違いがあるため。C-kも同様。ただし、Emacsバインドは様々なWebサイトで奪われるので、キーリマッパーのサポートはEmacsキーバインド自体に対しても結局必要がなことが多い">*3</a>、かつCommandキーのショートカットとデフォルトで分離されている</li> <li><a class="keyword" href="http://d.hatena.ne.jp/keyword/Windows">Windows</a>ほど対応アプリは多くないが、<a class="keyword" href="http://d.hatena.ne.jp/keyword/Linux">Linux</a>は対応してなくて<a class="keyword" href="http://d.hatena.ne.jp/keyword/macOS">macOS</a>は対応してるアプリは割りとある <a href="#f-65511216" name="fn-65511216" title="ライセンス時代の1Passwordとか、Appleなのでやや例外的ながらiTunesとか">*4</a></li> <li><a class="keyword" href="http://d.hatena.ne.jp/keyword/iPhone">iPhone</a>やそのアクセサリとの連携が最も自然に動く</li> <li><a class="keyword" href="http://d.hatena.ne.jp/keyword/OSS">OSS</a>の<a class="keyword" href="http://d.hatena.ne.jp/keyword/macOS">macOS</a>対応をするときに便利</li> </ul> <h2>悪い所</h2> <ul> <li>ターミナルの動作が<a class="keyword" href="http://d.hatena.ne.jp/keyword/Linux">Linux</a>のそれに比べて遅かったり、(<a class="keyword" href="http://d.hatena.ne.jp/keyword/Intel">Intel</a>の) フルスペックの<a class="keyword" href="http://d.hatena.ne.jp/keyword/MacBook%20Pro">MacBook Pro</a>なのに普通に<a class="keyword" href="http://d.hatena.ne.jp/keyword/IDE">IDE</a>使ってるだけで度々カーソルがグルグルして待たされるので、あまり快適にプログラミングできない。まだ試せてないけど、M1やM2だとこれが劇的に改善されていると期待している。</li> <li><a class="keyword" href="http://d.hatena.ne.jp/keyword/Linux">Linux</a>ではない。<a class="keyword" href="http://d.hatena.ne.jp/keyword/Linux">Linux</a>サーバーをいじるのが仕事な人は、<a class="keyword" href="http://d.hatena.ne.jp/keyword/Linux">Linux</a>にあるけど<a class="keyword" href="http://d.hatena.ne.jp/keyword/macOS">macOS</a>にはないか普通使わないツール <a href="#f-abed3447" name="fn-abed3447" title="具体的にはstrace、perf、gdbなど。gdbは使えないことはないが入れるのが若干面倒な上、普通Clangを使う場合lldbを使うのが無難なのでgdbはなかなか使わない。">*5</a> にも慣れておくと、便利なことがある。</li> <li>homebrewの依存管理がゆるふわなので、<a class="keyword" href="http://d.hatena.ne.jp/keyword/brew">brew</a>を使っているとある日突然so名がズレたりしていろいろ壊れることになる</li> <li>ウィンドウの半透明化 <a href="#f-feabca35" name="fn-feabca35" title="これ何に使ってるかというと、シングルディスプレイでエディタを全画面表示しながら、それに透かしてブラウザとSlackやTwitterを同時に眺めるということをやっている。Vimだとターミナルの半透明機能でいけるけど、IntelliJ IDEAとかを使ってるときにそれができなくて不便。">*6</a> が難しい。Deskoveryというアプリでできていたのが、Catalina以降は<a class="keyword" href="http://d.hatena.ne.jp/keyword/SIP">SIP</a>を切らないといけなくなった。</li> </ul> <h1><a class="keyword" href="http://d.hatena.ne.jp/keyword/Linux">Linux</a></h1> <p>過去にはArch <a class="keyword" href="http://d.hatena.ne.jp/keyword/Linux">Linux</a>や<a class="keyword" href="http://d.hatena.ne.jp/keyword/Gentoo">Gentoo</a>などの<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%C7%A5%A3%A5%B9%A5%C8%A5%EA%A5%D3%A5%E5%A1%BC%A5%B7%A5%E7%A5%F3">ディストリビューション</a>や、<a class="keyword" href="http://d.hatena.ne.jp/keyword/Awesome">Awesome</a>や<a class="keyword" href="http://d.hatena.ne.jp/keyword/xmonad">xmonad</a>などのウィンドウマネージャを試したので自分の環境以外の話もある程度わかるつもりだが、今は<a class="keyword" href="http://d.hatena.ne.jp/keyword/Ubuntu">Ubuntu</a>と<a class="keyword" href="http://d.hatena.ne.jp/keyword/GNOME">GNOME</a>なのでそれ特有の話が混ざってるかも。</p> <h2>良い所</h2> <ul> <li>ターミナルの動作が速い。エディタなども含め、マシン購入にかかる値段あたりの比較では一番軽快に動作する印象。</li> <li>Dockerを動かすときのオーバーヘッドが小さく、軽快に動作する</li> <li><a class="keyword" href="http://d.hatena.ne.jp/keyword/Linux">Linux</a>サーバーサイドエンジニアの場合、本番環境と手元の環境を揃えられる</li> <li>ある程度機能が揃ったキーリマッパー <a href="#f-44c8aa75" name="fn-44c8aa75" title="Rubyが好きな人は拙作 xremap や、Pythonが好きな人は xkeysnail など">*7</a> があり、<a class="keyword" href="http://d.hatena.ne.jp/keyword/Mac">Mac</a>っぽい<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%AD%A1%BC%A5%D0%A5%A4%A5%F3%A5%C9">キーバインド</a> <a href="#f-ce75536f" name="fn-ce75536f" title="CtrlでEmacsキーバインド、Ctrlじゃない修飾キーでコピーやペーストなど">*8</a> もある程度再現できる</li> <li><a class="keyword" href="http://d.hatena.ne.jp/keyword/Windows">Windows</a>と<a class="keyword" href="http://d.hatena.ne.jp/keyword/macOS">macOS</a>だけでなく<a class="keyword" href="http://d.hatena.ne.jp/keyword/Linux">Linux</a>もサポートしているデスクトップアプリは結構あり、開発以外の用途にも使う場合も、意外とある程度は普通に生活できる <a href="#f-48c8f2d6" name="fn-48c8f2d6" title="参考: https://k0kubun.hatenablog.com/entry/linux-desktop-2017">*9</a></li> <li>ウィンドウマネージャの自由度が高い。タイル型WMとかが使える。 <a href="#f-d7fd1032" name="fn-d7fd1032" title="macOSにもないこともないが、もともとそれを念頭にデザインされてないデスクトップ環境なので、僕が過去に試したものは微妙な挙動だった">*10</a></li> <li><a class="keyword" href="http://d.hatena.ne.jp/keyword/OSS">OSS</a>の<a class="keyword" href="http://d.hatena.ne.jp/keyword/Linux">Linux</a>対応をするときに便利</li> </ul> <h2>悪い所</h2> <ul> <li>ドライバーのサポートが不安。何かケーブルを繋ぐ度に「動くのか…?」とビクビクすることになる。例えばうっかり最新の<a class="keyword" href="http://d.hatena.ne.jp/keyword/GPU">GPU</a>を買うと、<a class="keyword" href="http://d.hatena.ne.jp/keyword/Nvidia">Nvidia</a>のドライバをいれれば動くがnouveauだと動かず、何らかの拍子に<a class="keyword" href="http://d.hatena.ne.jp/keyword/Nvidia">Nvidia</a>のドライバが抜けると、画面が映らない状態で<a class="keyword" href="http://d.hatena.ne.jp/keyword/Nvidia">Nvidia</a>のドライバをインストールする必要が発生するみたいな状況に陥ることもある。</li> <li>動かないアプリが多い。最近、Steamが<a class="keyword" href="http://d.hatena.ne.jp/keyword/Linux">Linux</a>に対応してるっぽくて驚いたけど、たとえばAmong UsとかはSteam Play (中身はProtonという、Wineベースの互換レイヤ) を使って起動できたりするのだが、ネットワーク接続が動かなくて、なんかそれを<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%C7%A5%D0%A5%C3%A5%B0">デバッグ</a>する<a class="keyword" href="http://d.hatena.ne.jp/keyword/Reddit">Reddit</a>スレが盛り上がってたりする。</li> <li>音を出すみたいな割りと基本的なところがデフォルトで動かなくてハマることがある。まあそういうのを直すのをエンジョイするのが<a class="keyword" href="http://d.hatena.ne.jp/keyword/Linux">Linux</a>みたいなところがある。</li> <li>HiDPIに対応してないアプリがある。<a class="keyword" href="http://d.hatena.ne.jp/keyword/Windows">Windows</a>と違って、文字が低解像度表示されるのではなく、文字が小さく表示されるか、何か画面を切り替えた時にウィンドウ幅が画面サイズ以上になっていたりする。</li> </ul> <h1>まとめ</h1> <p><blockquote data-conversation="none" class="twitter-tweet" data-lang="en"><p lang="ja" dir="ltr">(<a class="keyword" href="http://d.hatena.ne.jp/keyword/Mac">Mac</a>|<a class="keyword" href="http://d.hatena.ne.jp/keyword/Windows">Windows</a>|<a class="keyword" href="http://d.hatena.ne.jp/keyword/Linux">Linux</a>) じゃないとプログラミングできないとか言ってるうちは○○○なんですよ。(発言自粛)</p>&mdash; mattn (@mattn_jp) <a href="https://twitter.com/mattn_jp/status/1386947116044484609?ref_src=twsrc%5Etfw">April 27, 2021</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script> </p> <div class="footnote"> <p class="footnote"><a href="#fn-c0c1cd3c" name="f-c0c1cd3c" class="footnote-number">*1</a><span class="footnote-delimiter">:</span><span class="footnote-text"><a class="keyword" href="http://d.hatena.ne.jp/keyword/%C1%EB%BB%C8%A4%A4%A4%CE%CD%AB%DD%B5">窓使いの憂鬱</a>の派生プロジェクト</span></p> <p class="footnote"><a href="#fn-a94036d6" name="f-a94036d6" class="footnote-number">*2</a><span class="footnote-delimiter">:</span><span class="footnote-text">Ctrlで<a class="keyword" href="http://d.hatena.ne.jp/keyword/Emacs">Emacs</a><a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%AD%A1%BC%A5%D0%A5%A4%A5%F3%A5%C9">キーバインド</a>、Ctrlじゃない修飾キーでコピーやペーストなど</span></p> <p class="footnote"><a href="#fn-89c5c0b3" name="f-89c5c0b3" class="footnote-number">*3</a><span class="footnote-delimiter">:</span><span class="footnote-text">これ、ほとんどは<a class="keyword" href="http://d.hatena.ne.jp/keyword/Windows">Windows</a>や<a class="keyword" href="http://d.hatena.ne.jp/keyword/Linux">Linux</a>でも再現できるんだけど、じゃあ何が嬉しいかっていうと、例えばHomeやEndでC-aとC-eをエミュレートする時、論理行頭/末じゃなくて物理行頭/末になってしまうという違いがあるため。C-kも同様。ただし、<a class="keyword" href="http://d.hatena.ne.jp/keyword/Emacs">Emacs</a>バインドは様々なWebサイトで奪われるので、キーリマッパーのサポートは<a class="keyword" href="http://d.hatena.ne.jp/keyword/Emacs">Emacs</a><a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%AD%A1%BC%A5%D0%A5%A4%A5%F3%A5%C9">キーバインド</a>自体に対しても結局必要がなことが多い</span></p> <p class="footnote"><a href="#fn-65511216" name="f-65511216" class="footnote-number">*4</a><span class="footnote-delimiter">:</span><span class="footnote-text">ライセンス時代の1Passwordとか、<a class="keyword" href="http://d.hatena.ne.jp/keyword/Apple">Apple</a>なのでやや例外的ながら<a class="keyword" href="http://d.hatena.ne.jp/keyword/iTunes">iTunes</a>とか</span></p> <p class="footnote"><a href="#fn-abed3447" name="f-abed3447" class="footnote-number">*5</a><span class="footnote-delimiter">:</span><span class="footnote-text">具体的にはstrace、perf、<a class="keyword" href="http://d.hatena.ne.jp/keyword/gdb">gdb</a>など。<a class="keyword" href="http://d.hatena.ne.jp/keyword/gdb">gdb</a>は使えないことはないが入れるのが若干面倒な上、普通Clangを使う場合lldbを使うのが無難なので<a class="keyword" href="http://d.hatena.ne.jp/keyword/gdb">gdb</a>はなかなか使わない。</span></p> <p class="footnote"><a href="#fn-feabca35" name="f-feabca35" class="footnote-number">*6</a><span class="footnote-delimiter">:</span><span class="footnote-text">これ何に使ってるかというと、シングルディスプレイでエディタを全画面表示しながら、それに透かしてブラウザとSlackや<a class="keyword" href="http://d.hatena.ne.jp/keyword/Twitter">Twitter</a>を同時に眺めるということをやっている。<a class="keyword" href="http://d.hatena.ne.jp/keyword/Vim">Vim</a>だとターミナルの半透明機能でいけるけど、<a class="keyword" href="http://d.hatena.ne.jp/keyword/IntelliJ">IntelliJ</a> IDEAとかを使ってるときにそれができなくて不便。</span></p> <p class="footnote"><a href="#fn-44c8aa75" name="f-44c8aa75" class="footnote-number">*7</a><span class="footnote-delimiter">:</span><span class="footnote-text"><a class="keyword" href="http://d.hatena.ne.jp/keyword/Ruby">Ruby</a>が好きな人は拙作 xremap や、<a class="keyword" href="http://d.hatena.ne.jp/keyword/Python">Python</a>が好きな人は xkeysnail など</span></p> <p class="footnote"><a href="#fn-ce75536f" name="f-ce75536f" class="footnote-number">*8</a><span class="footnote-delimiter">:</span><span class="footnote-text">Ctrlで<a class="keyword" href="http://d.hatena.ne.jp/keyword/Emacs">Emacs</a><a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%AD%A1%BC%A5%D0%A5%A4%A5%F3%A5%C9">キーバインド</a>、Ctrlじゃない修飾キーでコピーやペーストなど</span></p> <p class="footnote"><a href="#fn-48c8f2d6" name="f-48c8f2d6" class="footnote-number">*9</a><span class="footnote-delimiter">:</span><span class="footnote-text">参考: <a href="https://k0kubun.hatenablog.com/entry/linux-desktop-2017">https://k0kubun.hatenablog.com/entry/linux-desktop-2017</a></span></p> <p class="footnote"><a href="#fn-d7fd1032" name="f-d7fd1032" class="footnote-number">*10</a><span class="footnote-delimiter">:</span><span class="footnote-text"><a class="keyword" href="http://d.hatena.ne.jp/keyword/macOS">macOS</a>にもないこともないが、もともとそれを念頭にデザインされてないデスクトップ環境なので、僕が過去に試したものは微妙な挙動だった</span></p> </div> k0kubun リモートワークを支える技術 hatenablog://entry/26006613721773317 2021-04-28T16:37:21+09:00 2021-04-28T16:41:07+09:00 コロナのせいでフルリモートになってから1年くらい、それ起因でPCのセットアップを度々いじっていて、今日で大体いい感じになった気がするので買ってよかったと思っているものをシェアする。 USB-C to Ethernet アダプタ Zoom をするときに "Your internet connection is unstable" と出ると不便なので、リモートワーク時代はインターネットにWi-Fiを使うのは避け、有線で繋ぐのが良い。ケーブル本数を抑えるため、USBも刺さる奴を使っている。部屋の配置と配線の都合で廊下のど真ん中をケーブルが横断する感じになりそれは不便なのだが、この問題は解決してない。… <p>コロナのせいでフルリモートになってから1年くらい、それ起因でPCのセットアップを度々いじっていて、今日で大体いい感じになった気がするので買ってよかったと思っているものをシェアする。</p> <h1>USB-C to <a class="keyword" href="http://d.hatena.ne.jp/keyword/Ethernet">Ethernet</a> アダプタ</h1> <iframe style="width:120px;height:240px;" marginwidth="0" marginheight="0" scrolling="no" frameborder="0" src="//ws-na.amazon-adsystem.com/widgets/q?ServiceVersion=20070822&OneJS=1&Operation=GetAdHtml&MarketPlace=US&source=ac&ref=qf_sp_asin_til&ad_type=product_link&tracking_id=k0kubun-20&marketplace=amazon&amp;region=US&placement=B0871ZL9TG&asins=B0871ZL9TG&linkId=f7af7b4f486d97f3dc6338c7461fc4e9&show_border=false&link_opens_in_new_window=false&price_color=333333&title_color=0066C0&bg_color=FFFFFF"> </iframe> <p>Zoom をするときに "Your internet connection is unstable" と出ると不便なので、リモートワーク時代はインターネットに<a class="keyword" href="http://d.hatena.ne.jp/keyword/Wi-Fi">Wi-Fi</a>を使うのは避け、有線で繋ぐのが良い。ケーブル本数を抑えるため、USBも刺さる奴を使っている。部屋の配置と配線の都合で廊下のど真ん中をケーブルが横断する感じになりそれは不便なのだが、この問題は解決してない。</p> <h1><a class="keyword" href="http://d.hatena.ne.jp/keyword/HDMI">HDMI</a> スプリッタ</h1> <iframe style="width:120px;height:240px;" marginwidth="0" marginheight="0" scrolling="no" frameborder="0" src="//ws-na.amazon-adsystem.com/widgets/q?ServiceVersion=20070822&OneJS=1&Operation=GetAdHtml&MarketPlace=US&source=ac&ref=tf_til&ad_type=product_link&tracking_id=k0kubun-20&marketplace=amazon&amp;region=US&placement=B089LPZ7FN&asins=B089LPZ7FN&linkId=d305019576dd4c25351eeeb4a76d292d&show_border=false&link_opens_in_new_window=false&price_color=333333&title_color=0066c0&bg_color=ffffff"> </iframe> <p>自宅に4Kディスプレイが1つだけあるのだが、パソコンは私用と社用で2つある。勤務開始と終了で毎日2回ディスプレイをつけかえるとき、<a class="keyword" href="http://d.hatena.ne.jp/keyword/HDMI">HDMI</a>を2本ディスプレイに刺しておいてディスプレイのボタンをポチポチしてもいいんだけど、毎日やるにはポチポチの回数が多くて面倒くさいので、ボタンを一回押すだけで切り替えられるととても便利。</p> <p>これを買う前は <a target="_blank" href="https://www.amazon.com/gp/product/B079JQ9XXV/ref=as_li_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=B079JQ9XXV&linkCode=as2&tag=k0kubun-20&linkId=3f71e16006584330bbf7a6e7995dd61e">別のHDMIスプリッタ</a> を使っていたのだが、どうもこれは電力供給がコネクタ1側に依存していて、そっちのマシンがスリープ状態になるともう一方の画面がたまに点滅するという問題があったので買い替えた。ほぼ同じ値段での買い替えでこの問題が解消できたのはよかった。</p> <h1>キーボード・マウス スイッチ</h1> <iframe style="width:120px;height:240px;" marginwidth="0" marginheight="0" scrolling="no" frameborder="0" src="https://rcm-fe.amazon-adsystem.com/e/cm?ref=tf_til&t=k0kubun05-22&m=amazon&o=9&p=8&l=as1&IS1=1&detail=1&asins=B0029ULLRU&linkId=f6d4cf4f87fed4bf9fa634e5d3c66f5b&bc1=FFFFFF&amp;lt1=_top&fc1=333333&lc1=0066C0&bg1=FFFFFF&f=ifr"> </iframe> <p>キーボードとマウスのUSBも毎日2回抜き刺しするのは明らかに面倒なので、これもボタン一つで切り替えられるようにしておくと便利。これだけはたまたま前から持ってるやつで、9年使っているが全く壊れてないし安いのでお勧め度が高い。</p> <p>ボタン1つで<a class="keyword" href="http://d.hatena.ne.jp/keyword/HDMI">HDMI</a>とUSBを両方同時に切り替えられる奴使った方が便利なんじゃないのと思うかもしれない。実際 <a target="_blank" href="https://www.amazon.com/gp/product/B07QM6ND7R/ref=as_li_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=B07QM6ND7R&linkCode=as2&tag=k0kubun-20&linkId=b6b832d554f1f08f358f6e52da2e7fa1">これ</a> と <a target="_blank" href="https://www.amazon.com/gp/product/B07Y34K4CY/ref=as_li_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=B07Y34K4CY&linkCode=as2&tag=k0kubun-20&linkId=308614876e8819b5aa22e1df4dbda4db">これ</a> を買って試したのだが、なんか画面の切り替えがうまく動かない不具合が頻発したので返品した。結果として、<a class="keyword" href="http://d.hatena.ne.jp/keyword/HDMI">HDMI</a>だけは別のボタンで切り替える方が安定性の観点から体験が良かった。</p> <h1>ヘッドホン to USB アダプタ</h1> <p><a target="_blank" href="https://www.amazon.co.jp/gp/product/B0786WWQR3/ref=as_li_tl?ie=UTF8&camp=247&creative=1211&creativeASIN=B0786WWQR3&linkCode=as2&tag=k0kubun05-22&linkId=d4fe187eee58f7d73845359321f5582e">Apple EarPods</a> は<a class="keyword" href="http://d.hatena.ne.jp/keyword/iPhone">iPhone</a>に付属してくる上に個別で買っても安く、形や耳障りがPixelのそれに比べて良く、音質も無難で、そのままマイクにもなるお気に入りのイヤホンなのだが、3.5mm 端子をそのへんのデスクトップマシンのライン出力に刺しても、マイク用端子は別なのでマイクが動かない。<a href="#f-9da89edf" name="fn-9da89edf" title="そもそも、元はデスクトップマシンでマイクを使う用事がなかったのでマシンごとに別のApple EarPodsをさして使っていたのだが、イヤホンが2つデスク上にあると、間違って今使ってない方のマシンに繋っている方をつけがちという問題もあった。大学院の授業のグループプロジェクトで毎週他の生徒とGoogle Meetで通話をする用事ができたので、私用マシンでもEarPodsでマイク使いたいなと思い、今回これら2つの問題を解決した。">*1</a></p> <p>ヘッドホンスプリッタを使えば普通はいいのだが、この辺の<a class="keyword" href="http://d.hatena.ne.jp/keyword/Apple">Apple</a>製品は非<a class="keyword" href="http://d.hatena.ne.jp/keyword/Apple">Apple</a>製品と互換性がないという噂があり、実際 <a target="_blank" href="https://www.amazon.com/gp/product/B01MQZ2023/ref=as_li_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=B01MQZ2023&linkCode=as2&tag=k0kubun-20&linkId=ea2ddb4236da62d767d61badd4258ccb">これ</a> を買ってみたが、<a class="keyword" href="http://d.hatena.ne.jp/keyword/Linux">Linux</a>では低音質でマイク入力ができるが<a class="keyword" href="http://d.hatena.ne.jp/keyword/Windows">Windows</a>では何故か全く使えないという感じだった。</p> <iframe style="width:120px;height:240px;" marginwidth="0" marginheight="0" scrolling="no" frameborder="0" src="//ws-na.amazon-adsystem.com/widgets/q?ServiceVersion=20070822&OneJS=1&Operation=GetAdHtml&MarketPlace=US&source=ac&ref=tf_til&ad_type=product_link&tracking_id=k0kubun-20&marketplace=amazon&amp;region=US&placement=B07K25P3N1&asins=B07K25P3N1&linkId=9eb68d8f49842846cb8a3d8e00b07413&show_border=false&link_opens_in_new_window=false&price_color=333333&title_color=0066c0&bg_color=ffffff"> </iframe> <p>なので、<a class="keyword" href="http://d.hatena.ne.jp/keyword/Apple">Apple</a>純正のUSB-C to ヘッドホンアダプタを買い、さらに <a target="_blank" href="https://www.amazon.com/gp/product/B085VT1VJT/ref=as_li_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=B085VT1VJT&linkCode=as2&tag=k0kubun-20&linkId=c88f7e3185c25588cd38d6960f7b1d93">USB-C to USB (Type-A) アダプタ</a> に接続してやる <a href="#f-4e9787a7" name="fn-4e9787a7" title="僕のデスクトップマシンにUSB-Cの口がないため。あとこれにより上述のスイッチが使える。">*2</a> ことで、社用<a class="keyword" href="http://d.hatena.ne.jp/keyword/MacBook%20Pro">MacBook Pro</a>と私用デスクトップマシンの<a class="keyword" href="http://d.hatena.ne.jp/keyword/Windows">Windows</a>と<a class="keyword" href="http://d.hatena.ne.jp/keyword/Linux">Linux</a>両方でマイクが綺麗な音で入るようになった。上述のUSBスイッチは2つしか口がないのだが、<a target="_blank" href="https://www.amazon.com/gp/product/B071JTSMVQ/ref=as_li_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=B071JTSMVQ&linkCode=as2&tag=k0kubun-20&linkId=a0baa4c344934fc8fdd1d49d2592288d">小さなUSBハブ</a> をつなげてやることで、1つのボタンでキーボードとマウスとイヤホンが全部切り替えられるようになった。</p> <p><span itemscope itemtype="http://schema.org/Photograph"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/k/k0kubun/20210428/20210428162840.jpg" alt="f:id:k0kubun:20210428162840j:plain" title="" class="hatena-fotolife" itemprop="image"></span></p> <p>最終的はこういう感じに落ちついた。便利。</p> <div class="footnote"> <p class="footnote"><a href="#fn-9da89edf" name="f-9da89edf" class="footnote-number">*1</a><span class="footnote-delimiter">:</span><span class="footnote-text">そもそも、元はデスクトップマシンでマイクを使う用事がなかったのでマシンごとに別の<a class="keyword" href="http://d.hatena.ne.jp/keyword/Apple">Apple</a> EarPodsをさして使っていたのだが、イヤホンが2つデスク上にあると、間違って今使ってない方のマシンに繋っている方をつけがちという問題もあった。大学院の授業のグループプロジェクトで毎週他の生徒と<a class="keyword" href="http://d.hatena.ne.jp/keyword/Google">Google</a> Meetで通話をする用事ができたので、私用マシンでもEarPodsでマイク使いたいなと思い、今回これら2つの問題を解決した。</span></p> <p class="footnote"><a href="#fn-4e9787a7" name="f-4e9787a7" class="footnote-number">*2</a><span class="footnote-delimiter">:</span><span class="footnote-text">僕のデスクトップマシンにUSB-Cの口がないため。あとこれにより上述のスイッチが使える。</span></p> </div> k0kubun Pryはもう古い、時代はIRB hatenablog://entry/26006613711521011 2021-04-02T21:14:55+09:00 2021-04-03T02:27:01+09:00 僕はRubyで開発をする時は毎回Pryを使うくらいの熱狂的Pryユーザーだったのだが、PryはGemfileに書いてないと binding.pry できなくて不便。任意のgemをdefault gem化するgem default コマンドも作ったのだが、これをやるのすら面倒だと思っていた。 ある日、nobuさんがRubyに binding.irb という機能をいれた。Pryがdefault gemになるのを待つよりPryで僕が使う機能をIRBに全部移植してしまった方が早いのではないかと思い、4年前からPryの機能の移植活動を始め、今日僕がよく使う機能を全て移植し終えた。 その記念に、この記事で… <p>僕は<a class="keyword" href="http://d.hatena.ne.jp/keyword/Ruby">Ruby</a>で開発をする時は毎回Pryを使うくらいの熱狂的Pryユーザーだったのだが、PryはGemfileに書いてないと <code>binding.pry</code> できなくて不便。任意のgemをdefault gem化する<a href="https://github.com/k0kubun/gem-default">gem default コマンド</a>も作ったのだが、これをやるのすら面倒だと思っていた。</p> <p>ある日、nobuさんが<a class="keyword" href="http://d.hatena.ne.jp/keyword/Ruby">Ruby</a>に <code>binding.irb</code> という機能をいれた。Pryがdefault gemになるのを待つよりPryで僕が使う機能を<a class="keyword" href="http://d.hatena.ne.jp/keyword/IRB">IRB</a>に全部移植してしまった方が早いのではないかと思い、4年前からPryの機能の移植活動を始め、今日僕がよく使う機能を全て移植し終えた。</p> <p>その記念に、この記事では<a class="keyword" href="http://d.hatena.ne.jp/keyword/IRB">IRB</a>のPry互換の機能を紹介する。昔 <a href="https://qiita.com/k0kubun/items/b118e9ccaef8707c4d9f">今更聞けないpryの使い方と便利プラグイン集</a> という記事を書いたんだけど、この中で僕が毎日のように使うコマンドは全て<a class="keyword" href="http://d.hatena.ne.jp/keyword/IRB">IRB</a>に移植したので、それを紹介する本稿を読むだけで今日からあなたも<a class="keyword" href="http://d.hatena.ne.jp/keyword/IRB">IRB</a>が便利に使えるようになる。</p> <h1><a class="keyword" href="http://d.hatena.ne.jp/keyword/IRB">IRB</a>のPry互換機能の変遷</h1> <p>新しめの機能が多いので、使えるようになったバージョンごとに機能を紹介する。</p> <h2><a class="keyword" href="http://d.hatena.ne.jp/keyword/Ruby">Ruby</a> 2.4</h2> <h3>binding.<a class="keyword" href="http://d.hatena.ne.jp/keyword/irb">irb</a></h3> <p>nobuさんが <code>binding.irb</code> を<a href="https://github.com/ruby/ruby/commit/493e48897421d176a8faf0f0820323d79ecdf94a">入れた</a>歴史的バージョン。この時点ではどこで起動されたかが表示されず、<code>binding.pry</code> の代わりとしては正直ちょっと不便かなという状態だった。ただ、標準ライブラリなのでGemfileに書いてなくても使えるのが強み。</p> <pre class="code rb" data-lang="rb" data-unlink>$ cat a.rb foo = &#34;hello world&#34; binding.irb $ ruby -rirb a.rb irb(main):001:0&gt; foo =&gt; &#34;hello world&#34;</pre> <h2><a class="keyword" href="http://d.hatena.ne.jp/keyword/Ruby">Ruby</a> 2.5</h2> <h3><a class="keyword" href="http://d.hatena.ne.jp/keyword/irb">irb</a>の自動require</h3> <p>nobuさんが次に、<code>binding.irb</code> をすると<a class="keyword" href="http://d.hatena.ne.jp/keyword/irb">irb</a>が自動でrequireされるという機能を<a href="https://github.com/ruby/ruby/commit/7802f01d4fcb9f237cac480364a09f788265fbbd">入れた</a>。pryはrequireしないと使えないので僕は<a class="keyword" href="http://d.hatena.ne.jp/keyword/Vim">Vim</a>に <code>inoremap &lt;C-v&gt; require "pry";binding.pry</code> という設定があるのだが、<code>binding.irb</code> はこんな面倒なことをしなくても使えるので、また一つPryにない強みができた。</p> <h3>binding.<a class="keyword" href="http://d.hatena.ne.jp/keyword/irb">irb</a> の周辺行表示</h3> <p>ここから僕が参戦。<a class="keyword" href="http://d.hatena.ne.jp/keyword/Ruby">Ruby</a> 2.5から、<code>binding.irb</code> の周辺行が表示されるように<a href="https://github.com/ruby/ruby/commit/106c9883e11673fa31e3854d7e24b97f4c1ba9fd">した</a>。やっぱりこれがないと使いにくい。この時点ではまだ白黒。</p> <pre class="code rb" data-lang="rb" data-unlink>$ ruby a.rb From: a.rb @ line 2 : 1: foo = &#34;hello world&#34; =&gt; 2: binding.irb irb(main):001:0&gt; foo =&gt; &#34;hello world&#34;</pre> <h2><a class="keyword" href="http://d.hatena.ne.jp/keyword/Ruby">Ruby</a> 2.6</h2> <h3>default gem化</h3> <p>hsbtさんが<a class="keyword" href="http://d.hatena.ne.jp/keyword/IRB">IRB</a>を<a href="https://github.com/ruby/ruby/commit/70785c1c5a7131ef51c145f13b508023b8589e63">default gem化</a>。<a class="keyword" href="http://d.hatena.ne.jp/keyword/Ruby">Ruby</a> 2.6になるまでは<a class="keyword" href="http://d.hatena.ne.jp/keyword/IRB">IRB</a>はgem化されてない標準ライブラリだった。gem化によって、Pryと同じように <code>gem install irb</code> でインストールやアップデートが可能になった。<code>gem install irb</code> さえしてしまえば、例えば<a class="keyword" href="http://d.hatena.ne.jp/keyword/Ruby">Ruby</a> 2.5でも最新の<a class="keyword" href="http://d.hatena.ne.jp/keyword/IRB">IRB</a>の機能が大体使える。Gemfileに書いてない限りは <code>bundle exec</code> してしまうとそれは使われないので、新しい<a class="keyword" href="http://d.hatena.ne.jp/keyword/Ruby">Ruby</a>を使うことはgem化された今でも重要である。</p> <h2><a class="keyword" href="http://d.hatena.ne.jp/keyword/Ruby">Ruby</a> 2.7</h2> <h3><a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%B7%A5%F3%A5%BF%A5%C3%A5%AF%A5%B9">シンタックス</a>ハイライト</h3> <p><a href="https://www.youtube.com/watch?v=vM9XfqlqyNw&amp;t=34s">僕の好きな標準ライブラリはRipper</a>なんだけど、その趣味を炸裂させて<a href="https://github.com/ruby/ruby/pull/2150">実装した</a>のが<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%B7%A5%F3%A5%BF%A5%C3%A5%AF%A5%B9">シンタックス</a>ハイライト。<code>binding.pry</code> での周辺行に色がつくようになり、本格的にPryっぽくなってきた。<code>IRB::Color</code> が標準添付の<a class="keyword" href="http://d.hatena.ne.jp/keyword/Ruby">Ruby</a><a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%B7%A5%F3%A5%BF%A5%C3%A5%AF%A5%B9">シンタックス</a>ハイライトライブラリとなり、<a href="https://github.com/k0kubun/hamlit/blob/v2.14.6/lib/hamlit/cli.rb#L125">個人gemで使ったり</a>している。なお、inspectの結果は<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%B7%A5%F3%A5%BF%A5%C3%A5%AF%A5%B9">シンタックス</a>ハイライトとは少し勝手が違うため、このバージョンでは<a class="keyword" href="http://d.hatena.ne.jp/keyword/Ruby">Ruby</a>の<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%EA%A5%C6%A5%E9%A5%EB">リテラル</a>としてvalidになるようなinspectのみ色がつく感じになっている。</p> <p><span itemscope itemtype="http://schema.org/Photograph"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/k/k0kubun/20210402/20210402210027.png" alt="f:id:k0kubun:20210402210027p:plain" title="" class="hatena-fotolife" itemprop="image"></span></p> <h3>インクリメンタルハイライト</h3> <p>このバージョンでaycabtaさんがreadline実装を彼が実装したRelineに差し替えたことで、入力行の描画のフックが容易になったため、1文字入力するごとに<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%B7%A5%F3%A5%BF%A5%C3%A5%AF%A5%B9">シンタックス</a>ハイライトする機能も<a href="https://github.com/ruby/ruby/pull/2202">実装できた</a>。Pryではこの機能は標準でなく、かつ<a href="https://rubygems.org/gems/pry-coolline">pry-coolline</a>はパフォーマンスに問題があるのかチラチラしてちょっと不快で、その点<a class="keyword" href="http://d.hatena.ne.jp/keyword/IRB">IRB</a>ではチラつきがないのでPryよりとても快適。</p> <p><blockquote data-conversation="none" class="twitter-tweet" data-lang="en"><p lang="ja" dir="ltr"><a class="keyword" href="http://d.hatena.ne.jp/keyword/Ruby">Ruby</a> 2.7の<a class="keyword" href="http://d.hatena.ne.jp/keyword/IRB">IRB</a>の開発が盛り上がりすぎて、ついにREPLの入力のインクリメンタル<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%B7%A5%F3%A5%BF%A5%C3%A5%AF%A5%B9">シンタックス</a>ハイライトを実装してしまった <a href="https://t.co/TKl3FhJ54Y">pic.twitter.com/TKl3FhJ54Y</a></p>&mdash; k0kubun (@k0kubun) <a href="https://twitter.com/k0kubun/status/1132179069523521539?ref_src=twsrc%5Etfw">May 25, 2019</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script> </p> <h2><a class="keyword" href="http://d.hatena.ne.jp/keyword/Ruby">Ruby</a> 3.1</h2> <p>これ以降の機能は<a class="keyword" href="http://d.hatena.ne.jp/keyword/Ruby">Ruby</a> 3.0がリリースされてから開発したため、リリース済みの<a class="keyword" href="http://d.hatena.ne.jp/keyword/Ruby">Ruby</a>には標準では入っていない。aycabtaさんがそろそろ<a class="keyword" href="http://d.hatena.ne.jp/keyword/IRB">IRB</a>のリリースをするらしいので、そのうち <code>gem install irb</code> では使えるようになる予定 (追記: 1.3.5でリリースされた)。バージョンが古くても以下のコマンドは使いたいなと思ったので、僕はirbrcに<a href="https://github.com/k0kubun/dotfiles/blob/d9196e045d4ad7206a7331e469b550b0423b61bc/config/.irbrc#L52-L239">当面の間ベタ書き</a>することにした。</p> <h3>複雑なオブジェクトのinspect色付け</h3> <p>inspect結果は<a class="keyword" href="http://d.hatena.ne.jp/keyword/Ruby">Ruby</a>としてvalidではないことがあるため<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%B7%A5%F3%A5%BF%A5%C3%A5%AF%A5%B9">シンタックス</a>ハイライトのコードが流用できないのだが、Pryの真似をしてmasterではこれを<a href="https://github.com/ruby/irb/pull/159">実装してある</a>。<code>ActiveRecord::Base</code> の<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%A4%A5%F3%A5%B9%A5%BF%A5%F3%A5%B9">インスタンス</a>も綺麗に色がつくようになったので <code>rails c</code> で便利。<code>IRB::ColorPrinter</code> が標準添付のinspect色付けライブラリとして使えるようになったので、power_assertもこれを使い始めたらしい。</p> <p><span itemscope itemtype="http://schema.org/Photograph"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/k/k0kubun/20210402/20210402210201.png" alt="f:id:k0kubun:20210402210201p:plain" title="" class="hatena-fotolife" itemprop="image"></span></p> <h3>ls コマンド</h3> <p>ここでやっとPry風の<a class="keyword" href="http://d.hatena.ne.jp/keyword/IRB">IRB</a>使いこなし記事っぽくなるのだが、Pryには <code>ls</code> というコマンドがあって、短い記述でメソッドや変数の一覧を調べられて便利。あまりにも欲しいのでこれを個人の <code>~/.irbrc</code> に実装して過ごしていたのだが、他の人も使いたいという声を見たので、最近<a class="keyword" href="http://d.hatena.ne.jp/keyword/IRB">IRB</a>本体に<a href="https://github.com/ruby/irb/pull/203">実装を移した</a>。とてもよく使う。Pryのcdっぽい機能は<a class="keyword" href="http://d.hatena.ne.jp/keyword/IRB">IRB</a>に既にあるが、個人的には <code>binding.pry</code> の貼り直しで済んじゃうことが多いので、Pryでもcdは最近あまり使わない。</p> <p><span itemscope itemtype="http://schema.org/Photograph"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/k/k0kubun/20210402/20210402210407.png" alt="f:id:k0kubun:20210402210407p:plain" title="" class="hatena-fotolife" itemprop="image"></span></p> <p>なお、<a class="keyword" href="http://d.hatena.ne.jp/keyword/IRB">IRB</a>では<a class="keyword" href="http://d.hatena.ne.jp/keyword/Ruby">Ruby</a>としてvalidな入力しかできないため、<code>-G</code> / <code>--grep</code> オプションで出力を<a class="keyword" href="http://d.hatena.ne.jp/keyword/grep">grep</a>するためには <code>~/.irbrc</code> に<a href="https://github.com/k0kubun/dotfiles/blob/d9196e045d4ad7206a7331e469b550b0423b61bc/config/.irbrc#L251-L258">ちょっと細工をする</a>必要がある。</p> <h3>show_source コマンド</h3> <p><a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%BD%A1%BC%A5%B9%A5%B3%A1%BC%A5%C9">ソースコード</a>リーディングに便利なのがPryの <code>show-source</code> なんだけど、<a class="keyword" href="http://d.hatena.ne.jp/keyword/IRB">IRB</a>では<a class="keyword" href="http://d.hatena.ne.jp/keyword/Ruby">Ruby</a>としてvalidな入力しかできないため、まずコマンド名が <code>show_source</code> になっていて、かつ引数も文字列<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%EA%A5%C6%A5%E9%A5%EB">リテラル</a>で書かないといけないことになっている。それでも便利かなと思って<a href="https://github.com/ruby/irb/pull/219">いれた</a>のだが、<code>~/.irbrc</code> に<a href="https://github.com/k0kubun/dotfiles/blob/d9196e045d4ad7206a7331e469b550b0423b61bc/config/.irbrc#L249-L250">細工</a>をすると以下の感じで <code>$</code> という短い<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%A8%A5%A4%A5%EA%A5%A2%A5%B9">エイリアス</a>で使える。</p> <p><span itemscope itemtype="http://schema.org/Photograph"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/k/k0kubun/20210402/20210402210556.png" alt="f:id:k0kubun:20210402210556p:plain" title="" class="hatena-fotolife" itemprop="image"></span></p> <h3>whereami コマンド</h3> <p>細かいが、<code>binding.irb</code> していろいろやると画面外に元の行が追い出されてわからなくなることがある。そういう時に便利なのが <code>whereami</code> で、再度 <code>binding.irb</code> が実行された行を表示することができる。 <code>~/.irbrc</code> に<a href="https://github.com/k0kubun/dotfiles/blob/d9196e045d4ad7206a7331e469b550b0423b61bc/config/.irbrc#L247-L271">細工</a>をすると短い <code>@</code> という<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%A8%A5%A4%A5%EA%A5%A2%A5%B9">エイリアス</a>で使える。</p> <p><span itemscope itemtype="http://schema.org/Photograph"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/k/k0kubun/20210402/20210402210739.png" alt="f:id:k0kubun:20210402210739p:plain" title="" class="hatena-fotolife" itemprop="image"></span></p> <h1><a class="keyword" href="http://d.hatena.ne.jp/keyword/IRB">IRB</a>は<a class="keyword" href="http://d.hatena.ne.jp/keyword/Ruby">Ruby</a>としてvalidでない入力もできるべきか</h1> <p><a class="keyword" href="http://d.hatena.ne.jp/keyword/IRB">IRB</a>はコマンドの実装が全てメソッド呼び出しなので、<code>ls -G</code>、<code>show-source</code>、<code>@</code> に関しては上記の通り <code>~/.irbrc</code> をいじらないとPryっぽく使えなくなっている。これを受け付けるのは周りの人があんまり乗り気じゃなさそうだったので一旦保留にしたけど、これが欲しいという世論が形成され、誰かが<a class="keyword" href="http://d.hatena.ne.jp/keyword/IRB">IRB</a>にマージできるような実装を書けば、皆が手元に <code>~/.irbrc</code> を持たなくても便利に使える日が来るかもしれない。</p> <h1>pry-byebugは?</h1> <p>僕は<a href="https://speakerdeck.com/k0kubun/how-i-debugged-debugger-number-rubykaigi-1">pry-byebugを10倍速くしたことがある</a>ので10倍速くしたことがない人よりは多分pry-byebugに思い入れがあるが、個人的には cd の話と同じく <code>binding.irb</code> の貼り直しで大体の用事が足りてしまうことが多く、いわゆるデバッガっぽい機能は使わなくても済んでしまうことが多い。</p> <p>しかし、ささださんが標準添付の debug.rb をいい感じにするプロジェクトを最近やっておられ、その過程で<a class="keyword" href="http://d.hatena.ne.jp/keyword/IRB">IRB</a>連携が導入される可能性があるため、そこで<a class="keyword" href="http://d.hatena.ne.jp/keyword/IRB">IRB</a>にデバッガ機能が標準でつくこともあるかも。</p> <h1>余談</h1> <p>昔は初心者がPryじゃなくて<a class="keyword" href="http://d.hatena.ne.jp/keyword/IRB">IRB</a>を使っていると馬鹿にされるということがあったという話を思い出した。今では初心者も安心して使えるREPLになってめでたい。</p> <p><blockquote data-conversation="none" class="twitter-tweet" data-lang="en"><p lang="ja" dir="ltr">「昨日text editingに使ってる奴馬鹿にされた」って言われて、エディタのことかなと思って聞いたら<a class="keyword" href="http://d.hatena.ne.jp/keyword/irb">irb</a>って返ってきて、<a class="keyword" href="http://d.hatena.ne.jp/keyword/irb">irb</a>でコード書いてるのか……と思ったけど単に初心者だからrepl叩いてみていて、pryを使えと馬鹿にされたという話だった</p>&mdash; k0kubun (@k0kubun) <a href="https://twitter.com/k0kubun/status/519290349097738240?ref_src=twsrc%5Etfw">October 7, 2014</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script> </p> <h1>Special Thanks</h1> <p>僕が<a class="keyword" href="http://d.hatena.ne.jp/keyword/IRB">IRB</a>にいれた機能は主にaycabtaさんにレビュー、リリースしていただきました。ありがとうございます!</p> k0kubun Java, MySQLをKotlin, PostgreSQLに移行した hatenablog://entry/26006613704053373 2021-03-16T19:53:49+09:00 2021-03-21T04:16:58+09:00 7年前にGitHub Rankingというサービスを作り、APIを叩きすぎてGitHubからの風当たりが強くなって*1からはデータの更新を止めていたが、KubernetesやGraphQLの時みたいに技術を試す砂場用に惰性で動かし続けていた。 Issueの機能要望対応が段々面倒になってきて、サーバー代節約のために潰すかと考えていたのだけど、毎日1000PVくらいあるので試しにGoogle Adsenseを設置してみたところ1日平均 $1 くらいは入ってて黒字になりそうだったので、ちょっとメンテしやすくしてデータの更新再開するかー、ということで今回いろいろ綺麗にした。 DB: MySQL → P… <p>7年前に<a href="https://gitstar-ranking.com/">GitHub Ranking</a>というサービスを作り、<a class="keyword" href="http://d.hatena.ne.jp/keyword/API">API</a>を叩きすぎて<a class="keyword" href="http://d.hatena.ne.jp/keyword/GitHub">GitHub</a>からの風当たりが強くなって<a href="#f-ba35ecb8" name="fn-ba35ecb8" title="この時についでに、サービス名にGitHubいれるのやめろと言われて、Gitstar Rankingという名前になった">*1</a>からはデータの更新を止めていたが、<a href="https://k0kubun.hatenablog.com/entry/kubernetes">Kubernetes</a>や<a href="https://k0kubun.hatenablog.com/entry/graphql">GraphQL</a>の時みたいに技術を試す砂場用に惰性で動かし続けていた。</p> <p>Issueの機能要望対応が段々面倒になってきて、サーバー代節約のために潰すかと考えていたのだけど、毎日1000PVくらいあるので試しに<a class="keyword" href="http://d.hatena.ne.jp/keyword/Google%20Adsense">Google Adsense</a>を設置してみたところ1日平均 $1 くらいは入ってて黒字になりそうだったので、ちょっとメンテしやすくしてデータの更新再開するかー、ということで今回いろいろ綺麗にした。</p> <h1>DB: <a class="keyword" href="http://d.hatena.ne.jp/keyword/MySQL">MySQL</a> → <a class="keyword" href="http://d.hatena.ne.jp/keyword/PostgreSQL">PostgreSQL</a></h1> <h2>なぜ<a class="keyword" href="http://d.hatena.ne.jp/keyword/PostgreSQL">PostgreSQL</a>にしたのか</h2> <p>個人的には多くの用途では<a class="keyword" href="http://d.hatena.ne.jp/keyword/MySQL">MySQL</a>と<a class="keyword" href="http://d.hatena.ne.jp/keyword/PostgreSQL">PostgreSQL</a>どっちでもいいと思っているんだけど、今所属してるチームがメンテしてるサービスのDBの多くが<a class="keyword" href="http://d.hatena.ne.jp/keyword/PostgreSQL">PostgreSQL</a>な割に自分はまだ<a class="keyword" href="http://d.hatena.ne.jp/keyword/PostgreSQL">PostgreSQL</a>の経験が浅いので、練習的な意味で<a class="keyword" href="http://d.hatena.ne.jp/keyword/PostgreSQL">PostgreSQL</a>に移行して慣らすことにした。</p> <h2>ConoHaのDBサーバー</h2> <p>ConoHaのDBサーバーは月500円でマネージド<a class="keyword" href="http://d.hatena.ne.jp/keyword/MySQL">MySQL</a>が使える素晴らしいサービスなのだけど、<a class="keyword" href="http://d.hatena.ne.jp/keyword/PostgreSQL">PostgreSQL</a>には対応していないのでこれをやめる必要があった。500円だと<a class="keyword" href="http://d.hatena.ne.jp/keyword/SSD">SSD</a> 10GBなんだけど、<a class="keyword" href="http://d.hatena.ne.jp/keyword/GitHub">GitHub</a>のDBをまるごとぶち抜いてくる都合上ストレージが足りなくなってきていたので、どの道何かする必要はあった。最初610円の<a class="keyword" href="http://d.hatena.ne.jp/keyword/VPS">VPS</a> (<a class="keyword" href="http://d.hatena.ne.jp/keyword/SSD">SSD</a> 30GB) を別途立ててそこに移行したけど、割りとメインの<a class="keyword" href="http://d.hatena.ne.jp/keyword/VPS">VPS</a>のキャパシティ余裕あるし、<a class="keyword" href="http://d.hatena.ne.jp/keyword/SSD">SSD</a>も100GBあるので、結局そっちに同居させた。</p> <h2>Embulkでデータ変換</h2> <p><a class="keyword" href="http://d.hatena.ne.jp/keyword/MySQL">MySQL</a>から<a class="keyword" href="http://d.hatena.ne.jp/keyword/PostgreSQL">PostgreSQL</a>へのデータ転送は皆Embulkでやってるイメージがあったので、<a href="https://qiita.com/777nancy/items/d5512bffab50a0796c5c">EmbulkでMySQLからPostgreSQLへデータ転送</a>という記事を参考に自分もそれでやってみた。DBはusersが1000万レコード、repositoriesが1800万レコードあったが、usersは数分で転送できて速いなと思った。</p> <p>repositoriesは<a href="https://qiita.com/shinyashikis@github/items/21b0fe4e710b397d28b6">この記事</a>に近いエラーになって、記事のように<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%BF%A5%A4%A5%E0%A5%A2%A5%A6%A5%C8">タイムアウト</a>伸ばすのを試したがそれでは直らなかった。transactionを使うところで落ちていたので、transactionを使わなくて済むようembulk-output-<a class="keyword" href="http://d.hatena.ne.jp/keyword/postgresql">postgresql</a>のmodeを<code>insert</code>から<code>insert_direct</code>に変えた。結局同じところで落ちて700万行だけinsertされた状態になったけど、usersさえ全部あればrepositoriesの復旧は大変ではないので、そのまま行くことにした…。</p> <h2>ridgepole → sqldef移行</h2> <p><a class="keyword" href="http://d.hatena.ne.jp/keyword/PostgreSQL">PostgreSQL</a>の<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%B9%A5%AD%A1%BC%A5%DE">スキーマ</a>をEmbulkのguessだけに頼って作ったため雑な<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%B9%A5%AD%A1%BC%A5%DE">スキーマ</a>になっていたので、UNIQUEやNOT NULLをつけるなど整理する必要があった。もともと<a href="https://github.com/winebarrel/ridgepole">Ridgepole</a>という<a class="keyword" href="http://d.hatena.ne.jp/keyword/ActiveRecord">ActiveRecord</a>ベースの羃等<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%B9%A5%AD%A1%BC%A5%DE">スキーマ</a>管理ツールを使っていて、これを使ってもいいのだが、<a href="https://k0kubun.hatenablog.com/entry/2018/08/25/114455">以前の記事</a>に書いた通りその<a class="keyword" href="http://d.hatena.ne.jp/keyword/ActiveRecord">ActiveRecord</a>非依存版である<a href="https://github.com/k0kubun/sqldef">sqldef</a>をメンテしているので、この機会にそれに移行した。移行は<code>sqldef --export</code>を叩くだけでできる。</p> <p>リリースしてから3年経ち、様々な方、特に<a href="https://twitter.com/sonots/status/1324342271987249153">ZOZO社の方面</a>からいっぱいバグレポートをいただき全て直してきたのでほとんど問題なく動いたが、<a href="https://github.com/k0kubun/sqldef/pull/97">最近いただいたパッチ</a>が<a class="keyword" href="http://d.hatena.ne.jp/keyword/PostgreSQL">PostgreSQL</a> 12に対応してなかったので<a href="https://github.com/k0kubun/sqldef/commit/0b1421ff106b87a13f13613b2e7147ba9d026fef">直したり</a>、次に伸べる<a href="https://github.com/k0kubun/sqldef/commit/1bc2ed9ec86d119f8eb51cace297d1bd61ee97da">citext拡張に対応したりした</a>。ついでに<a href="https://github.com/sqldef/sqldef-rails">sqldef-rails</a>というのも作った<a href="#f-a8046cf2" name="fn-a8046cf2" title="元々ActiveRecordが入っているRailsだとRidgepoleを使わない理由はほとんどない気がするけど、同じDBをActiveRecord以外からも読むので素のSQLで管理されてる方が扱いやすい (今回のアプリがそれ) とか、DDLは覚えてるけどActiveRecordのDSLは調べないとわからないというようなニッチな用途には便利かもしれない。">*2</a>。そのうちGradle<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%D7%A5%E9%A5%B0%A5%A4%A5%F3">プラグイン</a>も作りたい。</p> <h2>citext拡張</h2> <p><a class="keyword" href="http://d.hatena.ne.jp/keyword/MySQL">MySQL</a>と<a class="keyword" href="http://d.hatena.ne.jp/keyword/PostgreSQL">PostgreSQL</a>の違いは、ORDERなしでSELECTしてidでソートされないとか、AUTO_INCREMENTのかわりにserialとsequenceを使うとか、GET_LOCKのかわりに pg_advisory_xact_lock とか使うなどいろいろあったが、一番苦労したのは<a class="keyword" href="http://d.hatena.ne.jp/keyword/MySQL">MySQL</a>の文字列は普通<a class="keyword" href="http://d.hatena.ne.jp/keyword/case%20insensitive">case insensitive</a>だけど<a class="keyword" href="http://d.hatena.ne.jp/keyword/PostgreSQL">PostgreSQL</a>に移行した瞬間<a class="keyword" href="http://d.hatena.ne.jp/keyword/case%20sensitive">case sensitive</a>になってしまうというものだった。<a class="keyword" href="http://d.hatena.ne.jp/keyword/GitHub">GitHub</a>のユーザーや<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%EA%A5%DD%A5%B8%A5%C8%A5%EA">リポジトリ</a>の名前は<a class="keyword" href="http://d.hatena.ne.jp/keyword/case%20insensitive">case insensitive</a>で引きたいのである。</p> <p>これは LOWER(foo) にインデックスをかけて常に LOWER(foo) でfooを引いてやっても解決するが、常に LOWER(foo) するというのがいかにも忘れそうである。これを単に<a class="keyword" href="http://d.hatena.ne.jp/keyword/MySQL">MySQL</a>っぽい挙動にしてくれるのが <a href="https://www.postgresql.org/docs/9.1/citext.html">citext</a> (<a class="keyword" href="http://d.hatena.ne.jp/keyword/case-insensitive">case-insensitive</a> text) という型。<a class="keyword" href="http://d.hatena.ne.jp/keyword/psql">psql</a>や<a class="keyword" href="http://d.hatena.ne.jp/keyword/Rails">Rails</a>からアクセスすると<a class="keyword" href="http://d.hatena.ne.jp/keyword/case-insensitive">case-insensitive</a>にアクセスできたのが、<strong><a class="keyword" href="http://d.hatena.ne.jp/keyword/JDBC">JDBC</a>からアクセスするとなぜか<a class="keyword" href="http://d.hatena.ne.jp/keyword/case-sensitive">case-sensitive</a>になる</strong> というとこころにハマった。URLに <a href="https://github.com/jOOQ/jOOQ/issues/7093"><code>?stringtype=unspecified</code> をつける</a> と直るが、まさかクライアントが挙動をコン<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%C8%A5%ED%A1%BC%A5%EB">トロール</a>できると思ってなかったので、気付くのに時間がかかった。</p> <h1>Worker: <a class="keyword" href="http://d.hatena.ne.jp/keyword/Java">Java</a> → Kotlin</h1> <p>このサイトは<a class="keyword" href="http://d.hatena.ne.jp/keyword/Rails">Rails</a>で作られていてワーカーも元々Sidekiqで実装していたのだが、高速化のために100スレッドで<a class="keyword" href="http://d.hatena.ne.jp/keyword/API">API</a>を叩き<a class="keyword" href="http://d.hatena.ne.jp/keyword/ActiveRecord">ActiveRecord</a>を使うということをやったら<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%E1%A5%E2%A5%EA%A5%EA%A1%BC%A5%AF">メモリリーク</a>っぽい挙動になって詰んだので、それ以外を使う必要があった。僕が使える言語でこの要件だと多分Goが一番妥当なんだけど、現行のワーカー実装を書いた当時に<a href="https://www.slideshare.net/tagomoris/planetscale-data-ingestion-pipeline-bigdam#24">社のチーム</a>が使っていたスタックである<a class="keyword" href="http://d.hatena.ne.jp/keyword/Java">Java</a>、<a href="https://jdbi.org/">JDBI</a>、<a href="https://undertow.io/">Undertow</a> <a href="#f-9e8b1b1e" name="fn-9e8b1b1e" title="正確にはそれを自社でラップした Underwrap https://github.com/treasure-data/underwrap">*3</a>を練習用に使ったのであった<a href="#f-c76bdc2b" name="fn-c76bdc2b" title="ちなみに、MySQLのテーブル上に実装したキューにRailsからジョブをエンキューしてJavaのワーカーでデキューして処理するという普通はしない構成を取っていたのだけど、これはTreasure Dataでは頻出のパターンで、TDではRubyとJVMが一緒にワイワイしてないサービスを探す方が難しい">*4</a>。</p> <p>で、大体同じ人がいるチームに今もいるんだけど、<a class="keyword" href="http://d.hatena.ne.jp/keyword/JVM">JVM</a>では主にKotlin、<a href="https://www.jooq.org/">jOOQ</a>、<a href="https://www.dropwizard.io/en/latest/">Dropwizard</a>を使うように変わったので、普段使っているそれに差し替えることでメンテコストを下げることにした。<a class="keyword" href="http://d.hatena.ne.jp/keyword/JDK">JDK</a>も8から11に上げた。</p> <h2><a class="keyword" href="http://d.hatena.ne.jp/keyword/Java">Java</a>と比べたKotlinのいいところ</h2> <p>Kotlinのdata classを使うと<a class="keyword" href="http://d.hatena.ne.jp/keyword/Java">Java</a>より行数が減らせて便利みたいな話をすると、<a href="https://projectlombok.org/">Lombok</a>で十分という反応をしてくる人がいて、僕は<a class="keyword" href="http://d.hatena.ne.jp/keyword/Lombok">Lombok</a>は実際使ったことがあるわけではないけど<a href="https://www.slideshare.net/gishi/lombok-56265965">このスライド</a>とかに出てくる機能だけど見ると、以下の点でKotlinの方が便利かなあと感じる。</p> <ul> <li><a href="https://kotlinlang.org/docs/functions.html#named-arguments">Named arguments</a>をキーワード引数的に使える <a href="#f-e0393b5f" name="fn-e0393b5f" title="メソッドに引数が複数あると、その順序は自明じゃないと思うことが多い。なので順序を覚えてないとろくに呼び出せないメソッドは不親切だなと思っていて、例えばRubyでも引数が2〜3個に達したあたりで2つ目以降か全部の引数をキーワード引数にして呼んだりしていて、これができない言語は結構イライラする。静的型付言語なら引数の型合わなければコンパイルエラーになるし覚えなくていいんじゃない?と思うかもしれないが、同じ型が複数並ぶとその主張は崩壊する。なるべくNamed argumentsで呼び出してやることで、引数のリファクタリングとかも安全感が出る。">*5</a></li> <li>複数行文字列が綺麗に書ける <a href="#f-2ba2d99a" name="fn-2ba2d99a" title="JavaにJEP 326 https://openjdk.java.net/jeps/326 入らなかったの残念">*6</a></li> <li>String interpolationが便利</li> <li>標準でもList, Mapの操作が楽</li> <li>Lambdaが<a class="keyword" href="http://d.hatena.ne.jp/keyword/Java">Java</a>より書きやすい</li> <li><code>?:</code>, <code>let</code>, <code>also</code> みたいな便利な奴が何かと多い</li> <li>型でNull安全にできる</li> <li>throws書かなくていい</li> <li>extensionが便利、<a class="keyword" href="http://d.hatena.ne.jp/keyword/Ruby">Ruby</a>のrefinementsが気軽に使える感じ</li> <li>Smart castで型操作が楽になることがある</li> <li>coroutineで気軽に軽量なIO多重化ができる</li> </ul> <h2>jOOQ</h2> <p><a href="https://jdbi.org/">JDBI</a>は生の<a class="keyword" href="http://d.hatena.ne.jp/keyword/SQL">SQL</a>を毎回書く奴だけど、<a href="https://www.jooq.org/">jOOQ</a>は<a class="keyword" href="http://d.hatena.ne.jp/keyword/SQL">SQL</a>風の<a class="keyword" href="http://d.hatena.ne.jp/keyword/DSL">DSL</a>でクエリをビルドする。JDBIは複雑なクエリを動的に組み立てるみたいなのにはあんまり向いてなくて、実際社で僕が<a href="https://github.com/CanCanCommunity/cancancan">cancancan</a>Kotlinに移植した奴はクエリが動的に変わりまくるのでjOOQが活躍している。また、KotlinのNamed argumentsとjOOQを組合せるとオプショナルなキーワード引数でクエリを動的に変える感じにできるので、<a href="https://github.com/k0kubun/gitstar-ranking/blob/master/worker/src/main/kotlin/com/github/k0kubun/gitstar_ranking/db/UserQuery.kt#L71-L87">ActiveRecord風のインターフェース</a>が作りやすい。</p> <p>普通はテーブルごとにコード生成をして使う奴なんだけど、使い始めた当初Kotlinのコード生成がうまく動いてなかった都合、コード生成なしで使っている。ただ、<code>onDuplicateKeyUpdate</code> とかがコード生成用の<a class="keyword" href="http://d.hatena.ne.jp/keyword/API">API</a>を使わないと使えないのは困った<a href="#f-d79e0852" name="fn-d79e0852" title="コード生成用に用意されてるAPIを自分で呼び出した。まあ、今はコード生成使ったらいいんだけど">*7</a>。</p> <h2>Dropwizard</h2> <p>ワーカーなのにUndertowで<a class="keyword" href="http://d.hatena.ne.jp/keyword/API">API</a>を生やしていたのはワーカーの操作用<a class="keyword" href="http://d.hatena.ne.jp/keyword/API">API</a>を生やしていたからだが、メンテコストに対して利益が薄いので<a class="keyword" href="http://d.hatena.ne.jp/keyword/API">API</a>は落とした。なのでDropwizardはここでは使っていないのだが、Dropwizardには<a href="https://www.dropwizard.io/en/latest/manual/core.html#organizing-your-project">パッケージ構成指針</a>があって、これに従っていると<a class="keyword" href="http://d.hatena.ne.jp/keyword/Rails">Rails</a>みたいにどこに何があるか予測しやすいのが気にいっていて、このワーカーでもなるべくDropwizardっぽい感じで物を配置することで普段と同じ感じで色々探せるようにした。</p> <h2>Jersey Client</h2> <p>Dropwizardは<a class="keyword" href="http://d.hatena.ne.jp/keyword/JAX-RS">JAX-RS</a>ベースなので、<a href="https://github.com/opentracing-contrib/java-jaxrs">opentracing-contrib/java-jaxrs</a>でOpenTracingに対応できるのだが、<a class="keyword" href="http://d.hatena.ne.jp/keyword/API">API</a>クライアントにも<a class="keyword" href="http://d.hatena.ne.jp/keyword/JAX-RS">JAX-RS</a>ベースのものを使えば同じものでOpenTracingに対応できるので、<a class="keyword" href="http://d.hatena.ne.jp/keyword/JAX-RS">JAX-RS</a>のクライアントの参照実装であるJersey Clientが弊チームでは使われている。このワーカーでは適当に見つけた<a class="keyword" href="http://d.hatena.ne.jp/keyword/google">google</a>-http-clientを使っていたのだが、今回Jersey Clientに差し替えた。</p> <p>Jersey Clientでリク<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%A8%A5%B9">エス</a>トを投げるとstatus codeに応じた例外を投げることができるんだけど、レスポンスヘッダに入っているRate Limitの残りを見るために一旦 <code>Response</code> を取るとその機能は使えないので自分で投げる必要がある、という仕様に<a class="keyword" href="http://d.hatena.ne.jp/keyword/JAX-RS">JAX-RS</a>がなってるのがちょっと困った。</p> <h1>Server: <a class="keyword" href="http://d.hatena.ne.jp/keyword/Rails">Rails</a></h1> <p><a href="https://gitstar-ranking.com">https://gitstar-ranking.com</a> を返してるのは<a class="keyword" href="http://d.hatena.ne.jp/keyword/Rails">Rails</a>で、<a href="https://k0kubun.hatenablog.com/entry/ruby26-jit">RubyのJIT</a>や自作の<a href="https://k0kubun.hatenablog.com/entry/fastest-hamlit">最速テンプレートエンジン</a>である<a href="https://github.com/k0kubun/hamlit">hamlit</a>が試せるので特に他の何かに移行することなく続投。バージョンアップや使ってないGemの整理だけを行なった。</p> <h2><a class="keyword" href="http://d.hatena.ne.jp/keyword/Ubuntu">Ubuntu</a> 20.04</h2> <p><a class="keyword" href="http://d.hatena.ne.jp/keyword/Ubuntu">Ubuntu</a> 18.04 で動いていたのでアップグレードした。プロビジョニングは<a href="https://github.com/itamae-kitchen/mitamae">mitamae</a>で自動化しているものの、ConoHaをポチポチするのが面倒だったのでおもむろに <code>sudo do-release-upgrade</code> をしたが、<a class="keyword" href="http://d.hatena.ne.jp/keyword/Ruby">Ruby</a>が <code>libffi.so.6</code> で No such file or directory になったので<a class="keyword" href="http://d.hatena.ne.jp/keyword/Ruby">Ruby</a>をビルドし直して、それで終わり。</p> <h2><a class="keyword" href="http://d.hatena.ne.jp/keyword/Ruby">Ruby</a> 3.0</h2> <p><a class="keyword" href="http://d.hatena.ne.jp/keyword/Ruby">Ruby</a> 2.6だったのを<a class="keyword" href="http://d.hatena.ne.jp/keyword/Ruby">Ruby</a> 3.0に上げた。個人的には<a href="https://bugs.ruby-lang.org/issues/16746">endless method definition</a> <a href="#f-4d94d98c" name="fn-4d94d98c" title="この機能見る度にKotlin https://kotlinlang.org/docs/functions.html#single-expression-functions を思い出す">*8</a> がお気に入り。逆に、2.7で入った<a href="https://github.com/ruby/ruby/blob/v2_7_0/NEWS#label-Numbered+parameters">Numbered parameters</a>は、使いたい状況には度々遭遇するけど、Kotlinの<code>it</code>や<a class="keyword" href="http://d.hatena.ne.jp/keyword/Scala">Scala</a>の<code>_</code>に比べると<code>_1</code>という字面が微妙なので妥協で <code>{ |x| x</code> と書くことが多い <a href="#f-f48c9e49" name="fn-f48c9e49" title="これに関してはCommiter vs the worldか何かの時の投票でそういう立場であると表明しているので、ここでおもむろに意見を出してるわけではない">*9</a> 。</p> <h2><a class="keyword" href="http://d.hatena.ne.jp/keyword/Rails">Rails</a> 6.1</h2> <p><a class="keyword" href="http://d.hatena.ne.jp/keyword/Rails">Rails</a> 5.1から6.1に上げた。最近は<a class="keyword" href="http://d.hatena.ne.jp/keyword/Rails">Rails</a>のアップグレードは <code>bundle update</code> と <code>bin/rails app:update</code> するだけで終了で、あまり困らない感じになってきた。むしろ<a class="keyword" href="http://d.hatena.ne.jp/keyword/Ruby">Ruby</a> 3に上げる時はHashでキーワード引数渡してたところがおもむろに壊れたので、今回は<a class="keyword" href="http://d.hatena.ne.jp/keyword/Ruby">Ruby</a>の方がアップグレード難易度が高かった。<a class="keyword" href="http://d.hatena.ne.jp/keyword/Rails">Rails</a> 6といえば公式に複数DBやbulk insertに対応したなどがあって、どっちもこのアプリでは使わなかったが、地味に<a class="keyword" href="http://d.hatena.ne.jp/keyword/ActiveRecord">ActiveRecord</a>の <code>pick</code> は使った。</p> <h2>GraphQL退役</h2> <p>GraphQLで<a class="keyword" href="http://d.hatena.ne.jp/keyword/API">API</a>を生やしているところがあったが、ここ以外でgraphql-<a class="keyword" href="http://d.hatena.ne.jp/keyword/ruby">ruby</a>を一切使ってなくて何も覚えてないので<a class="keyword" href="http://d.hatena.ne.jp/keyword/Rails">Rails</a> Wayからあまりにも外れたこれをメンテするのがしんどいのと、ほとんどの<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%B9%A5%AD%A1%BC%A5%DE">スキーマ</a>は単に実装してみたくて生やしただけだったのでGraphQLは撤去した。<a class="keyword" href="http://d.hatena.ne.jp/keyword/JavaScript">JavaScript</a>から使われていた<a class="keyword" href="http://d.hatena.ne.jp/keyword/API">API</a>が一つだけあったが、それのために<a class="keyword" href="http://d.hatena.ne.jp/keyword/jbuilder">jbuilder</a>を依存に足したくなかったので、<code>render json:</code> だけで済ませた。</p> <h2>React, Webpacker退役</h2> <p>毎日使っている<a href="https://k0kubun.hatenablog.com/entry/2016/03/21/114626">TwitterクライアントをReactで自作</a>してそこそこメンテを続けているのでReactの使い方は普通に覚えているのだが、このアプリではユーザー更新ページで部分的に使っているだけだった割りにnpmのライブラリの<a class="keyword" href="http://d.hatena.ne.jp/keyword/%C0%C8%BC%E5%C0%AD">脆弱性</a>アラートが無限に来るのが<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%B3%A5%B9%A5%D1">コスパ</a>悪いなと思ったので、素の<a class="keyword" href="http://d.hatena.ne.jp/keyword/JavaScript">JavaScript</a>に書き直して、yarnとWebpackerもやめてSprocketsから配布することにした。モダンWebフロントエンドの素振りはどの道<a class="keyword" href="http://d.hatena.ne.jp/keyword/Twitter">Twitter</a>クライアントの方でやり続けるのでこちらではいいかなと。</p> <h2>Sprockets 4移行</h2> <p>長い間betaだったが去年やっと出たSprockets 4にアップグレードした。manifest.js というのを書かないといけなくなるのが面倒でサボっていたが、<a href="https://github.com/rails/sprockets/blob/master/UPGRADING.md">sprockets/UPGRADING.md</a>を見たら割りとすぐいけた。</p> <h2>Omniauth 2移行</h2> <p>Omniauth 1の<a class="keyword" href="http://d.hatena.ne.jp/keyword/%C0%C8%BC%E5%C0%AD">脆弱性</a>アラートが出ていたので上げようとしたのだが、DeviseとかいうGemがOmniauthのバージョン番号をチェックして例外を投げていて、しかもそのチェックを修正したバージョンが未だにリリースされていないのでDeviseはmasterを使う必要があった。それから、Omniauth 2に上げたらコールバックがGETじゃなくてPOST必須になり、そしてPOSTに変えると<a class="keyword" href="http://d.hatena.ne.jp/keyword/CSRF">CSRF</a> protectionに引っかかるという問題があった。<a href="https://stackoverflow.com/questions/17513829/devise-omniauth-call-action-passthru-on-login-facebook">Stackoverflow</a>で<a href="https://github.com/cookpad/omniauth-rails_csrf_protection">cookpad/omniauth-rails_csrf_protection</a>が紹介されていて、メンテナが信頼できそうなのでありがたく導入させていだたいた。</p> <h1>感想</h1> <p>データの更新を再開しつつ壊れた時にメンテしやすいようにしただけで機能追加とかは一切してないので、このサイトの<a class="keyword" href="http://d.hatena.ne.jp/keyword/Google%20Adsense">Google Adsense</a>の収益がこれで増える気はしないが、jOOQやJersey周りで仕事中に気になってたけど時間の都合触れてなかった部分をいろいろ試せたりとか、sqldefの<a class="keyword" href="http://d.hatena.ne.jp/keyword/PostgreSQL">PostgreSQL</a>対応の改善に繋ったのでよかった。</p> <div class="footnote"> <p class="footnote"><a href="#fn-ba35ecb8" name="f-ba35ecb8" class="footnote-number">*1</a><span class="footnote-delimiter">:</span><span class="footnote-text">この時についでに、サービス名に<a class="keyword" href="http://d.hatena.ne.jp/keyword/GitHub">GitHub</a>いれるのやめろと言われて、Gitstar Rankingという名前になった</span></p> <p class="footnote"><a href="#fn-a8046cf2" name="f-a8046cf2" class="footnote-number">*2</a><span class="footnote-delimiter">:</span><span class="footnote-text">元々<a class="keyword" href="http://d.hatena.ne.jp/keyword/ActiveRecord">ActiveRecord</a>が入っている<a class="keyword" href="http://d.hatena.ne.jp/keyword/Rails">Rails</a>だとRidgepoleを使わない理由はほとんどない気がするけど、同じDBを<a class="keyword" href="http://d.hatena.ne.jp/keyword/ActiveRecord">ActiveRecord</a>以外からも読むので素の<a class="keyword" href="http://d.hatena.ne.jp/keyword/SQL">SQL</a>で管理されてる方が扱いやすい (今回のアプリがそれ) とか、<a class="keyword" href="http://d.hatena.ne.jp/keyword/DDL">DDL</a>は覚えてるけど<a class="keyword" href="http://d.hatena.ne.jp/keyword/ActiveRecord">ActiveRecord</a>の<a class="keyword" href="http://d.hatena.ne.jp/keyword/DSL">DSL</a>は調べないとわからないというようなニッチな用途には便利かもしれない。</span></p> <p class="footnote"><a href="#fn-9e8b1b1e" name="f-9e8b1b1e" class="footnote-number">*3</a><span class="footnote-delimiter">:</span><span class="footnote-text">正確にはそれを自社でラップした Underwrap <a href="https://github.com/treasure-data/underwrap">https://github.com/treasure-data/underwrap</a></span></p> <p class="footnote"><a href="#fn-c76bdc2b" name="f-c76bdc2b" class="footnote-number">*4</a><span class="footnote-delimiter">:</span><span class="footnote-text">ちなみに、<a class="keyword" href="http://d.hatena.ne.jp/keyword/MySQL">MySQL</a>のテーブル上に実装したキューに<a class="keyword" href="http://d.hatena.ne.jp/keyword/Rails">Rails</a>からジョブをエンキューして<a class="keyword" href="http://d.hatena.ne.jp/keyword/Java">Java</a>のワーカーでデキューして処理するという普通はしない構成を取っていたのだけど、これはTreasure Dataでは頻出のパターンで、TDでは<a class="keyword" href="http://d.hatena.ne.jp/keyword/Ruby">Ruby</a>と<a class="keyword" href="http://d.hatena.ne.jp/keyword/JVM">JVM</a>が一緒にワイワイしてないサービスを探す方が難しい</span></p> <p class="footnote"><a href="#fn-e0393b5f" name="f-e0393b5f" class="footnote-number">*5</a><span class="footnote-delimiter">:</span><span class="footnote-text">メソッドに引数が複数あると、その順序は自明じゃないと思うことが多い。なので順序を覚えてないとろくに呼び出せないメソッドは不親切だなと思っていて、例えば<a class="keyword" href="http://d.hatena.ne.jp/keyword/Ruby">Ruby</a>でも引数が2〜3個に達したあたりで2つ目以降か全部の引数をキーワード引数にして呼んだりしていて、これができない言語は結構イライラする。静的型付言語なら引数の型合わなければ<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%B3%A5%F3%A5%D1%A5%A4%A5%EB">コンパイル</a>エラーになるし覚えなくていいんじゃない?と思うかもしれないが、同じ型が複数並ぶとその主張は崩壊する。なるべくNamed argumentsで呼び出してやることで、引数の<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%EA%A5%D5%A5%A1%A5%AF%A5%BF%A5%EA%A5%F3%A5%B0">リファクタリング</a>とかも安全感が出る。</span></p> <p class="footnote"><a href="#fn-2ba2d99a" name="f-2ba2d99a" class="footnote-number">*6</a><span class="footnote-delimiter">:</span><span class="footnote-text"><a class="keyword" href="http://d.hatena.ne.jp/keyword/Java">Java</a>にJEP 326 <a href="https://openjdk.java.net/jeps/326">https://openjdk.java.net/jeps/326</a> 入らなかったの残念</span></p> <p class="footnote"><a href="#fn-d79e0852" name="f-d79e0852" class="footnote-number">*7</a><span class="footnote-delimiter">:</span><span class="footnote-text">コード生成用に用意されてる<a class="keyword" href="http://d.hatena.ne.jp/keyword/API">API</a>を自分で呼び出した。まあ、今はコード生成使ったらいいんだけど</span></p> <p class="footnote"><a href="#fn-4d94d98c" name="f-4d94d98c" class="footnote-number">*8</a><span class="footnote-delimiter">:</span><span class="footnote-text">この機能見る度にKotlin <a href="https://kotlinlang.org/docs/functions.html#single-expression-functions">https://kotlinlang.org/docs/functions.html#single-expression-functions</a> を思い出す</span></p> <p class="footnote"><a href="#fn-f48c9e49" name="f-f48c9e49" class="footnote-number">*9</a><span class="footnote-delimiter">:</span><span class="footnote-text">これに関してはCommiter vs the worldか何かの時の投票でそういう立場であると表明しているので、ここでおもむろに意見を出してるわけではない</span></p> </div> k0kubun USのITIN申請と確定申告 hatenablog://entry/26006613701624542 2021-03-10T16:45:42+09:00 2021-03-21T20:02:50+09:00 5月末までにGoogleにtax infoを送らないとアメリカがYouTubeの広告収益の最大24%を課税するぞ、というメールが最近YouTuberに届いているらしく*1、そこに入力するTIN*2どうする? マイナンバーでいいの*3? ITIN 申請が必要なの? という話が盛り上がっている。 僕はアメリカで確定申告をする身だしYouTuberでもないのでこの話とは直接関係ないんだけど、妻のITINの申請をちょうど最近したところだったので、忘れないうちに何をしたか書いておく。 ITINとは Individual Tax Identification Number。日本におけるマイナンバーはアメリ… <p>5月末までに<a class="keyword" href="http://d.hatena.ne.jp/keyword/Google">Google</a>にtax infoを送らないと<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%A2%A5%E1%A5%EA">アメリ</a>カが<a class="keyword" href="http://d.hatena.ne.jp/keyword/YouTube">YouTube</a>の広告収益の最大24%を課税するぞ、というメールが最近YouTuberに届いているらしく<a href="#f-2d42ad74" name="fn-2d42ad74" title="YouTuberの https://twitter.com/mametter さん情報">*1</a>、そこに入力するTIN<a href="#f-5d99c708" name="fn-5d99c708" title="Tax Identification Number">*2</a>どうする? <a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%DE%A5%A4%A5%CA%A5%F3">マイナン</a>バーでいいの<a href="#f-0d6ef851" name="fn-0d6ef851" title="良さそうという情報も見た https://www.j-cast.com/2021/03/10406776.html">*3</a>? ITIN 申請が必要なの? という話が<a href="https://twitter.com/yenma/status/1369409534943522822">盛り上がっている</a>。</p> <p>僕は<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%A2%A5%E1%A5%EA">アメリ</a>カで確定申告をする身だしYouTuberでもないのでこの話とは直接関係ないんだけど、妻のITINの申請をちょうど最近したところだったので、忘れないうちに何をしたか書いておく。</p> <h1>ITINとは</h1> <p>Individual Tax Identification Number。日本における<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%DE%A5%A4%A5%CA%A5%F3">マイナン</a>バーは<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%A2%A5%E1%A5%EA">アメリ</a>カでは<a class="keyword" href="http://d.hatena.ne.jp/keyword/Social%20Security%20Number">Social Security Number</a>と呼ばれ、<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%A2%A5%E1%A5%EA">アメリ</a>カ人や<a class="keyword" href="http://d.hatena.ne.jp/keyword/%BD%A2%CF%AB%A5%D3%A5%B6">就労ビザ</a>の人はSSNを持ってるんだけど、SSNは非<a class="keyword" href="http://d.hatena.ne.jp/keyword/%BD%A2%CF%AB%A5%D3%A5%B6">就労ビザ</a>の人には付与されないので、SSNがない人が取得できるのがITIN。</p> <p><a href="https://k0kubun.hatenablog.com/entry/us-bootstrap">US移住とブートストラップ問題</a>に書いたが、確定申告の他、銀行や<a class="keyword" href="http://d.hatena.ne.jp/keyword/%B0%E5%CE%C5%CA%DD%B8%B1">医療保険</a>に加入する時にSSNかITINの提出が必要で、当然ながらクレカや<a class="keyword" href="http://d.hatena.ne.jp/keyword/%B0%E5%CE%C5%CA%DD%B8%B1">医療保険</a>なしでは<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%A2%A5%E1%A5%EA">アメリ</a>カでは生きていけないので、ITINがないのは実質人権がない状態に等しい。とはいえそういう状況であることを説明すると実際には入れるんだが、ネットの申請が空欄だと弾かれて電話が必要だったりとか、ITINを申請したくても<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%A2%A5%E1%A5%EA">アメリ</a>カ人はITINを申請したことがないので周りの人が誰もやり方を知らない、といったところで困りが発生するという感じ。</p> <h2>ITINの申請に必要なもの</h2> <p><a href="https://jp.usembassy.gov/ja/u-s-citizen-services-ja/itin-ja/">在日米国大使館・領事館のサイト</a>におおまかな流れは書いてあるが、これは結局英語の<a href="https://www.irs.gov/pub/irs-pdf/iw7.pdf">Instructions for Form W-7</a>を読まないとよくわからん感じになっている。これのHow To Applyのところをまとめると:</p> <ul> <li><a href="https://www.irs.gov/pub/irs-pdf/fw7.pdf">W-7</a> <ul> <li><a href="https://www.irs.gov/pub/irs-pdf/iw7.pdf">Instructions for Form W-7</a>に従って書かないといけないだけの普通の申請用紙。</li> </ul> </li> <li>ITINが必要な確定申告 <ul> <li>Exceptions Tables に該当する場合は不要</li> </ul> </li> <li>身分証明書の原本か認証コピー <ul> <li>米国入国日付のあるパスポートか、その認証コピー(Certified Copy)があればそれ一本でOK。他の書類だと多分2つ送る感じになる。</li> </ul> </li> </ul> <p>うちも最初はExceptions Tablesで申請しようとして会社からサインをもらおうとしたのだけど、HRがITINなしでも<a class="keyword" href="http://d.hatena.ne.jp/keyword/%B0%E5%CE%C5%CA%DD%B8%B1">医療保険</a>はいけるの一点張りで結局もらえず、そして<a class="keyword" href="http://d.hatena.ne.jp/keyword/%B0%E5%CE%C5%CA%DD%B8%B1">医療保険</a>の方からは必要だと返され3か月くらいたらい回しが続き、死ぬほど消耗したのでこれは諦めた。なので、正攻法の確定申告時の申請をした。</p> <p>郵送で申請する場合、日常的に郵便がロストする<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%A2%A5%E1%A5%EA">アメリ</a>カでパスポートを郵送するというのはちょっとありえないので、パスポートの認証コピーを取得することになる。<a href="https://www.sf.us.emb-japan.go.jp/itpr_ja/m03_03_07.html">日本領事館</a>のサイトにやり方が書いてある。予約制だが、人気なので予約の確保が難しい</p> <p>注意しなければならないのは、ITINが届くまでに申請から最悪<a href="https://www.irs.gov/individuals/how-do-i-apply-for-an-itin">7週間かかりうる</a>ので、もし<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%DE%A5%A4%A5%CA%A5%F3">マイナン</a>バーがTINに使えないとしたら、5月までにITINが必要なYouTuberは今すぐ申請しないと手遅れである。うちも2/24に先方に郵便が届いた通知をもらってからまだITINは来てないし、確定申告で追納したチェックもまだ引き落とされておらず、日々震えている。</p> <h1>Tax Return</h1> <p>ここからはITINに一切関係なくなるが、その申請書類の一部であった確定申告でやったことを書いておく。なお、申告期限が4/15から7/15に<a href="https://www.reuters.com/article/us-health-coronavirus-usa-taxes/u-s-house-democrats-demand-irs-to-extend-tax-filing-deadline-to-july-15-idUSKBN2B0248">伸びそう</a>なので、W-7で早めに提出しろと書かれているITIN申請者でもない限りは、まだ焦る必要はない。</p> <h2>日本の確定申告</h2> <p>日本の収入も<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%A2%A5%E1%A5%EA">アメリ</a>カで課税対象になるので、日本の収入がある人は先に日本の確定申告書類を作り、納税額だけでも確認しておく必要がある。</p> <h2>税理士 vs TurboTax</h2> <p>移住した直後のTax Returnは、大企業Armのご厚意により日本と<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%A2%A5%E1%A5%EA">アメリ</a>カの確定申告両方の面倒を見てくれる税理士が手配されたため、2019年分の確定申告はほとんど何もしなかったのだが、それは移住直後だけの提供だったので今回の2020年分から自分持ちになった。</p> <p>税理士を頼むと、確定申告をする時にその人の名前で提出することになるので、うっかり申告ミスがあった場合にも自分が捕まるリスクがやや低くできる気がする。ただ、単に自分がケチなのと、今後節税ができるように自分で仕組みを理解したかったというのがあり、今回はTurboTax <a href="#f-82621e10" name="fn-82621e10" title="Deluxeプラン。税理士よりは大分安そう">*4</a>を使って自分でやることにした。別にTurboTaxしかツールがないわけじゃないけど、タイムラインの日本人はTurboTaxを使っている人が多く感じる。</p> <h1>TurboTax</h1> <p>実際に自分で確定申告する時に何が必要が書いておく。必要な書類は大体1月に来るんだけど、申告を終えてから3月に来たやつとか、そもそも額が低すぎてフォームが来ない (ただし報告義務はある) やつとかがあり、やっていく必要がある。</p> <h2>My Info</h2> <p>Married Filing JointlyだとTax Bracketが安くなるので、配偶者の情報をいれる。SSNかITINの入力が必要だが、ITIN申請の瞬間はないので、何度もエラーを出されながらも空欄で進める。後でもう一度聞かれるけど、扶養者の情報もここで聞かれる。</p> <h2>Federal: Income &amp; Expenses</h2> <h3>W-2: Job</h3> <p>会社から郵送されてくる、<a class="keyword" href="http://d.hatena.ne.jp/keyword/%B8%BB%C0%F4%C4%A7%BC%FD%C9%BC">源泉徴収票</a>に相当するやつ。会社が使っているADPという給与明細サイトがTurboTaxと連携していて自動で入力されたが、Otherに書いてあるAT401というのが自動でカテゴライズされなくて、そこだけ自分で適当な奴を選ぶまでエラーになっていた。</p> <h3>1099-<a class="keyword" href="http://d.hatena.ne.jp/keyword/NEC">NEC</a>: Self-employment income and expenses</h3> <p><a class="keyword" href="http://d.hatena.ne.jp/keyword/Uber">Uber</a>ドライバーの収入とかが該当する奴。去年<a class="keyword" href="http://d.hatena.ne.jp/keyword/GitHub">GitHub</a> Sponsorsを始めたので、これが<a class="keyword" href="http://d.hatena.ne.jp/keyword/GitHub">GitHub</a>から郵送されてきた。全く<a class="keyword" href="http://d.hatena.ne.jp/keyword/%B8%BB%C0%F4%C4%A7%BC%FD">源泉徴収</a>されてないのでここで納税するんだけど、経費を入れると控除することができて、<a href="https://k0kubun.hatenablog.com/entry/ryzen7-5800x">年末に注文したRyzen代</a>などをここに充てた。インターネット代は普通いけるらしいけど、電気代<a href="#f-03d9677e" name="fn-03d9677e" title="Silicon Valley Powerに比べて、PG&amp;amp;Eめっちゃ高くて困っている">*5</a>はどうなんだろう。</p> <h3>1099-INT: Interest</h3> <p>銀行口座の利息がここで課税される。$10以下だとFormが郵送されてこないが報告義務はあるという<a href="https://twitter.com/katryo/status/1363296940469874691">話</a>を見たので、今回は安全側に倒し、思いつく全てを申告した。</p> <ul> <li>Bank of America: 額が小さいからか、TurboTax連携に失敗。Formも来ないし、サイトにもTax statementなし。自分で利息合計を計算して入力。</li> <li>Chase: サインアップボーナスが$200で、これが利息に分類されるらしい<a href="#f-63f6ffe6" name="fn-63f6ffe6" title="実際6か月加入してないとexpireするので見掛け上利息感はある">*6</a>。Formが郵送され、TurboTax連携も動いた。</li> <li>Amex HYSA: $10を超える程度には利息がついていたので、Formが郵送され、TurboTax連携も動いた。</li> <li>Charles Schwab: Vanguardに乗り換えるまで使ってた証券口座だけど、サインアップボーナスの$200がこれに分類された。アカウント削除済みだった<a href="#f-5f349247" name="fn-5f349247" title="郵送されてこなかったら確認が面倒な感じになるので、不要になったアカウントもTax Returnまでは取っておくのが良い…">*7</a>ので、郵送されてきた奴をスキャンしてアップロードした。</li> <li>Vanguard: サイトに1099-INTがあったけど $0 だったので何もなし。</li> </ul> <h3>1099-DIV: Dividends</h3> <p>株とかの配当。<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%A2%A5%E1%A5%EA">アメリ</a>カのTax-Exempt Bondのインデックスを<a class="keyword" href="http://d.hatena.ne.jp/keyword/%CA%DD%CD%AD">保有</a>していた結果、dividendsの<a href="https://personal.vanguard.com/pdf/INBST_012021.pdf">アメリカ全51州とグアム、プエルトリコへの分散</a>を計算して入力するという修行を行なうことになったのだが、<a href="https://twitter.com/draftcode/status/1363753358415122433">yuskさんとdraftcodeさんの議論</a>の結果、カリフォルニアの割合が50%超えてない以上は州税は一切免除にならなそうなので、単にMultiple Statesを入力して終わりとすればいいらしい。</p> <h3>1099-OID: Foreign Accounts</h3> <p><a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%A2%A5%E1%A5%EA">アメリ</a>カ国外に資産が $10,000 あると、Tax Returnとは別にFBARという奴を申告しておかないといけない。Tax Returnには影響しないんだけど、国内外の合計資産が $2M 超えていると<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%B0%A5%EA%A1%BC%A5%F3%A5%AB%A1%BC%A5%C9">グリーンカード</a>破棄する時に総資産の2〜3割を<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%A2%A5%E1%A5%EA">アメリ</a>カに取られるというExpatriate Taxがあるので、まあそういう奴とか<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%DE%A5%CD%A1%BC%A5%ED%A5%F3%A5%C0%A5%EA%A5%F3%A5%B0">マネーロンダリング</a>とかのための監視なんじゃないだろうか。まだやってないんだけどそのうち申請する。やり方は<a href="https://www.irs.gov/businesses/small-businesses-self-employed/report-of-foreign-bank-and-financial-accounts-fbar">IRSのサイト</a>に書いてあるが、電子申告できる。</p> <h3>1099-B: Stocks, Mutual Funds, Bonds, Other</h3> <p>株とかの<a class="keyword" href="http://d.hatena.ne.jp/keyword/%CA%DD%CD%AD">保有</a>量を書いておく。VanguardをTurboTaxに連携して終わり。</p> <h3>1099-K: Payment Card and Third Party Network Transactions</h3> <p>2020年分にはなかったけど、最近<a href="https://twitter.com/k0kubun/status/1365570408292904961">アメリカのメルカリを使った</a>ので、来年はこれが該当する。$20,000 売り上げないとFormが送られてこないけど、報告義務はあるので手動申告になる見込み<a href="#f-36ff154f" name="fn-36ff154f" title="https://www.mercari.com/us/help_center/article/163 https://turbotax.intuit.com/tax-tips/irs-tax-forms/form-1099-k-decoded-for-the-self-employed/L6xHSTXwR">*8</a>。</p> <h3>2555-T: Foreign Earned Income and Exclusion</h3> <p>日本とかの収入を入力する。<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%C9%A5%EB%B1%DF">ドル円</a>はIRSのサイトの<a href="https://www.irs.gov/individuals/international-taxpayers/yearly-average-currency-exchange-rates">Average Currency Exchange Rates</a>で変換しておくと安心そう。これを入力するまではめっちゃ還付されるやんという感じだったのが、これをいれた瞬間Tax Bracketが一段上になって税率が爆増してしまい、Foreign Tax Creditで日本側の大部分<a href="#f-a3f83626" name="fn-a3f83626" title="そもそもこれにリミットがあっが全額引かれてないので、普通に二重課税を食らっているというのも不満">*9</a>は控除されるにも関わらず、税率増加が主に<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%A2%A5%E1%A5%EA">アメリ</a>カi分に効いて死ぬほど追徴されることになった。</p> <h2>Federal: Deductions &amp; Credits</h2> <p>以下に紹介する奴の他に、Estimated Tax PaymentsとかHSAとかもここに入る。来年はEstimated Tax Paymentsも入力することになりそう…</p> <h3>Child and Other Dependent Tax Credit</h3> <p>扶養者の情報をいれる。小さい子供がいるとTax Creditが$2,000もらえる。ところでBiden's Covid relief billでこの額が増えるらしいけど、まあ当然ながらincomeが高いとphase outする。</p> <h3>Car Registration Fees</h3> <p>車の登録料が控除に使える。レシート破棄したけど、<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%EC%A5%B8%A5%B9%A5%C8%A5%EC%A1%BC%A5%B7%A5%E7%A5%F3">レジストレーション</a>の紙に $275 と書いてあった。<a href="#f-987e3107" name="fn-987e3107" title="Form 1014, line 12でstandard deductionを選択した場合は車の登録費は控除できないらしい https://twitter.com/yusk_/status/1369569396792823819">*10</a></p> <h3>1098-T: Expenses and Scholarships</h3> <p>大学の授業料が控除に使えるらしい。僕も学生なので1098-Tもらったし、教科書だったドラゴンブックを経費にしちゃうぞーとか考えてたけど、"Your income exceeds the maximum limit" だった。さようなら。</p> <h3>Medical Expenses</h3> <p>医療費が $18,171 を超えてると控除に使えるらしい。そんな使うことある…? 出産があったけど麻酔とかも保険でカバーされたし、保険でカバーされない金歯を3本いれたけど、金の値段は日本と同じなので、$18,171 もしない。明日歯医者に行って<a class="keyword" href="http://d.hatena.ne.jp/keyword/FMX">FMX</a>というレントゲンをやるんだけど、これが3年に1度しか保険でカバーされなくて $154 する<a href="#f-03272a1c" name="fn-03272a1c" title="引っ越して初回なのでこれをやるだけで、以降は毎年2回保険でカバーされるレントゲンしかやらないらしい">*11</a>んだが、$18,171 もしない…</p> <h3>Foreign Tax Credit</h3> <p>日本との二重課税を避けるためのやつ。10年とかキャリーオーバーできるらしいけど、その上限にも一発で達したっぽい。申告方法は二択で、Form 1116の方が税額が小さくできるらしいんだけど、auditされるリスクもこちらの方が高いらしい。でも、ここの税額があまりにも大きかったので僕はForm 1116一択で、日本の給与をGeneral category incomeとして申告した。</p> <h2>State: Your State Returns</h2> <p>Federalを入力すると、Stateの方にほとんど自動でコピーされてくるので、こっちでやることはほとんどない。 最初に "Made an estimated tax or extension payment over $20,000" か "Filed an original return with a tax liability over $80,000" であるか聞かれるが、2020年は該当してない気がするのでスルー。2021年は前者が該当しそう?</p> <h3>1095-B: Health Coverage</h3> <p><a class="keyword" href="http://d.hatena.ne.jp/keyword/%B0%E5%CE%C5%CA%DD%B8%B1">医療保険</a>。Kaiserから郵送されてきた。娘は産まれてからの加入だったので加入月を入力したが、通常は年中加入している、で終わりな気がする。</p> <h3>Underpayment Penalty</h3> <p><a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%A2%A5%E1%A5%EA">アメリ</a>カが日本の収入から<a class="keyword" href="http://d.hatena.ne.jp/keyword/%B8%BB%C0%F4%C4%A7%BC%FD">源泉徴収</a>をしてくれない<a href="#f-b52a4524" name="fn-b52a4524" title="当たり前なんだが">*12</a>せいで、特に州税が死ぬほど追徴された結果<a href="#f-bb9a2f8e" name="fn-bb9a2f8e" title="流石カリフォルニア">*13</a>、元々払ってた額が少なすぎということでペナルティが課せられた。来年のそれを避けるためか、TurboTaxが予定納税っぽい紙を印刷してきた。</p> <h2>郵送</h2> <p>普通はインターネットで提出と支払いをして終わりなんだけど、ITINの申請の際は郵送か対面で出す必要があり、郵送することにした。Tax Returnのための本来の住所ではなく、ITINの申請用の住所に送らないといけないことに注意。</p> <p>パスポートのCertified Copyがロストするとあまりにも面倒くさすぎる状況になったので、確実に届くようPriority Mail Expressで送った。自分で封筒持っていったけど現地に置いてある専用の封筒じゃないと出せないというミス。ラベルは自宅で購入、印刷して<a class="keyword" href="http://d.hatena.ne.jp/keyword/USPS">USPS</a>に持っていくことができる。専用の封筒への貼り付けも自分でやる必要がある。まあ多分来年は郵送しないけど…</p> <h1>感想</h1> <p>給料2か月分くらい追徴されてワロタ。初のTax Returnで不安なので早く受理されてITINが届いてほしい。</p> <div class="footnote"> <p class="footnote"><a href="#fn-2d42ad74" name="f-2d42ad74" class="footnote-number">*1</a><span class="footnote-delimiter">:</span><span class="footnote-text">YouTuberの <a href="https://twitter.com/mametter">https://twitter.com/mametter</a> さん情報</span></p> <p class="footnote"><a href="#fn-5d99c708" name="f-5d99c708" class="footnote-number">*2</a><span class="footnote-delimiter">:</span><span class="footnote-text">Tax Identification Number</span></p> <p class="footnote"><a href="#fn-0d6ef851" name="f-0d6ef851" class="footnote-number">*3</a><span class="footnote-delimiter">:</span><span class="footnote-text">良さそうという情報も見た <a href="https://www.j-cast.com/2021/03/10406776.html">https://www.j-cast.com/2021/03/10406776.html</a></span></p> <p class="footnote"><a href="#fn-82621e10" name="f-82621e10" class="footnote-number">*4</a><span class="footnote-delimiter">:</span><span class="footnote-text">Deluxeプラン。税理士よりは大分安そう</span></p> <p class="footnote"><a href="#fn-03d9677e" name="f-03d9677e" class="footnote-number">*5</a><span class="footnote-delimiter">:</span><span class="footnote-text">Silicon Valley Powerに比べて、PG&amp;Eめっちゃ高くて困っている</span></p> <p class="footnote"><a href="#fn-63f6ffe6" name="f-63f6ffe6" class="footnote-number">*6</a><span class="footnote-delimiter">:</span><span class="footnote-text">実際6か月加入してないとexpireするので見掛け上利息感はある</span></p> <p class="footnote"><a href="#fn-5f349247" name="f-5f349247" class="footnote-number">*7</a><span class="footnote-delimiter">:</span><span class="footnote-text">郵送されてこなかったら確認が面倒な感じになるので、不要になったアカウントもTax Returnまでは取っておくのが良い…</span></p> <p class="footnote"><a href="#fn-36ff154f" name="f-36ff154f" class="footnote-number">*8</a><span class="footnote-delimiter">:</span><span class="footnote-text"><a href="https://www.mercari.com/us/help_center/article/163">https://www.mercari.com/us/help_center/article/163</a> <a href="https://turbotax.intuit.com/tax-tips/irs-tax-forms/form-1099-k-decoded-for-the-self-employed/L6xHSTXwR">https://turbotax.intuit.com/tax-tips/irs-tax-forms/form-1099-k-decoded-for-the-self-employed/L6xHSTXwR</a></span></p> <p class="footnote"><a href="#fn-a3f83626" name="f-a3f83626" class="footnote-number">*9</a><span class="footnote-delimiter">:</span><span class="footnote-text">そもそもこれにリミットがあっが全額引かれてないので、普通に二重課税を食らっているというのも不満</span></p> <p class="footnote"><a href="#fn-987e3107" name="f-987e3107" class="footnote-number">*10</a><span class="footnote-delimiter">:</span><span class="footnote-text">Form 1014, line 12でstandard deductionを選択した場合は車の登録費は控除できないらしい <a href="https://twitter.com/yusk_/status/1369569396792823819">https://twitter.com/yusk_/status/1369569396792823819</a></span></p> <p class="footnote"><a href="#fn-03272a1c" name="f-03272a1c" class="footnote-number">*11</a><span class="footnote-delimiter">:</span><span class="footnote-text">引っ越して初回なのでこれをやるだけで、以降は毎年2回保険でカバーされるレントゲンしかやらないらしい</span></p> <p class="footnote"><a href="#fn-b52a4524" name="f-b52a4524" class="footnote-number">*12</a><span class="footnote-delimiter">:</span><span class="footnote-text">当たり前なんだが</span></p> <p class="footnote"><a href="#fn-bb9a2f8e" name="f-bb9a2f8e" class="footnote-number">*13</a><span class="footnote-delimiter">:</span><span class="footnote-text">流石カリフォルニア</span></p> </div> k0kubun 8年ぶりに vimrc を書き直した hatenablog://entry/26006613698830318 2021-03-03T20:29:53+09:00 2021-03-04T17:54:40+09:00 2013年にEmacsの使いすぎで小指が痛くなってからVimユーザーをやり始めて、かれこれ8年が経つ。 当時書いたvimrcを秘伝のタレ的に使い続けてきたが、正直あんまりまともにプラグインの更新とかをやっていなかったせいで、ある日突然、普通に使ってるだけなのにエラーが出まくって困る状態になった。 Vim の寿命 後ろめたさを感じつつも NeoBundle.vim、neocomplete.vim、Unite.vim といった一世代古いShougoさんウェアを使い続けていて、特に Unite.vim は後述の都合により2014年のバージョンに固定して更新をサボっていたのだが、Unite関係の何かが… <p>2013年に<a class="keyword" href="http://d.hatena.ne.jp/keyword/Emacs">Emacs</a>の使いすぎで小指が痛くなってから<a class="keyword" href="http://d.hatena.ne.jp/keyword/Vim">Vim</a>ユーザーをやり始めて、かれこれ8年が経つ。 当時書いたvimrcを秘伝のタレ的に使い続けてきたが、正直あんまりまともに<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%D7%A5%E9%A5%B0%A5%A4%A5%F3">プラグイン</a>の更新とかをやっていなかったせいで、ある日突然、普通に使ってるだけなのにエラーが出まくって困る状態になった。</p> <p><figure class="figure-image figure-image-fotolife" title="Slack"><span itemscope itemtype="http://schema.org/Photograph"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/k/k0kubun/20210303/20210303201233.png" alt="f:id:k0kubun:20210303201233p:plain" title="" class="hatena-fotolife" itemprop="image"></span></figure></p> <h2><a class="keyword" href="http://d.hatena.ne.jp/keyword/Vim">Vim</a> の寿命</h2> <p>後ろめたさを感じつつも NeoBundle.<a class="keyword" href="http://d.hatena.ne.jp/keyword/vim">vim</a>、neocomplete.<a class="keyword" href="http://d.hatena.ne.jp/keyword/vim">vim</a>、Unite.<a class="keyword" href="http://d.hatena.ne.jp/keyword/vim">vim</a> といった一世代古いShougoさんウェアを使い続けていて、特に Unite.<a class="keyword" href="http://d.hatena.ne.jp/keyword/vim">vim</a> は後述の都合により2014年のバージョンに固定して更新をサボっていたのだが、Unite関係の何かが<a class="keyword" href="http://d.hatena.ne.jp/keyword/Vim">Vim</a> 8.2で動かなくなった<a href="#f-d838a2ce" name="fn-d838a2ce" title="Vim 8.2がLuaに互換性がなくなったことによるもので、unite.vim最新版では修正済みとのことです https://twitter.com/ShougoMatsu/status/1367281209638674432">*1</a>。<a class="keyword" href="http://d.hatena.ne.jp/keyword/macOS">macOS</a>ではsystem <a class="keyword" href="http://d.hatena.ne.jp/keyword/Vim">Vim</a>を使うようにしてみたところ、system <a class="keyword" href="http://d.hatena.ne.jp/keyword/Ruby">Ruby</a>が何か壊れているせいでif_<a class="keyword" href="http://d.hatena.ne.jp/keyword/ruby">ruby</a>で書いている自作のUnite<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%D7%A5%E9%A5%B0%A5%A4%A5%F3">プラグイン</a>が常にバックトレースを吐く状態になった。</p> <p><a class="keyword" href="http://d.hatena.ne.jp/keyword/Linux">Linux</a>でも、neocompleteが特定のバージョン以上だと動かないという警告を見てからその直前のバージョンの<a class="keyword" href="http://d.hatena.ne.jp/keyword/Vim">Vim</a>を手動<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%B3%A5%F3%A5%D1%A5%A4%A5%EB">コンパイル</a>することで耐えていた。仮にその問題がなくとも、if_<a class="keyword" href="http://d.hatena.ne.jp/keyword/ruby">ruby</a>を使っているせいでそれと+clipboardがついてる<a class="keyword" href="http://d.hatena.ne.jp/keyword/Vim">Vim</a>がapt installで入れられず、よく<a class="keyword" href="http://d.hatena.ne.jp/keyword/Vim">Vim</a>を温かみのある手動<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%B3%A5%F3%A5%D1%A5%A4%A5%EB">コンパイル</a>をするハメになり、不便だなあと思っていた。</p> <p>何かと不便な点を直したかったのと、仕事で使っている<a class="keyword" href="http://d.hatena.ne.jp/keyword/macOS">macOS</a>のマシンで<a class="keyword" href="http://d.hatena.ne.jp/keyword/Vim">Vim</a>が全く使えない状態が致命的だったので、思い腰を上げて vimrc を書き直すことにした。</p> <h2>NeoVim 移行</h2> <p><span itemscope itemtype="http://schema.org/Photograph"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/k/k0kubun/20210303/20210303203118.png" alt="f:id:k0kubun:20210303203118p:plain" title="" class="hatena-fotolife" itemprop="image"></span></p> <p><a href="https://twitter.com/giginet">@giginet</a> が昔 <a href="https://giginet.hateblo.jp/entry/2015/11/24/203823">neovimが実用段階になったようなのでvimを置き換えてみた話</a> を書いてたのを見てからずっと気になっていたので、今回試してみることにした。 vimrcを読みにいく場所が違うので、(<a class="keyword" href="http://d.hatena.ne.jp/keyword/Linux">Linux</a>では) ちゃんと動く普通の<a class="keyword" href="http://d.hatena.ne.jp/keyword/Vim">Vim</a>でス<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%AF%A5%E9%A5%C3%A5%C1">クラッチ</a>の設定ファイルを書きNeoVimでそれをテストするというのにちょっと便利だった。</p> <p>Shougoさんの新しい<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%D7%A5%E9%A5%B0%A5%A4%A5%F3">プラグイン</a>の<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%B5%A5%D5%A5%A3%A5%C3%A5%AF%A5%B9">サフィックス</a>が.nvimなことや、<a href="https://github.com/roxma/vim-hug-neovim-rpc">roxma/vim-hug-neovim-rpc</a>というNeoVimのRPC (MessagePackを使っているらしい) を<a class="keyword" href="http://d.hatena.ne.jp/keyword/Vim">Vim</a>用に変換するという<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%EF%A1%BC%A5%AF%A5%A2%A5%E9%A5%A6%A5%F3%A5%C9">ワークアラウンド</a>っぽい方法で<a class="keyword" href="http://d.hatena.ne.jp/keyword/Vim">Vim</a>がサポートされているのを知っていたので、それらの<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%D7%A5%E9%A5%B0%A5%A4%A5%F3">プラグイン</a>を使う以上はNeoVimにしておいた方が筋が良さそうと思っていたというのもある。挙動は大体同じで、あともしかしたら速いんじゃないかと期待したけどそこはあまり変わらなかった。</p> <h2><a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%D7%A5%E9%A5%B0%A5%A4%A5%F3">プラグイン</a>の廃止と更新</h2> <p>まず、Shougoさんの<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%D7%A5%E9%A5%B0%A5%A4%A5%F3">プラグイン</a>3つを新しくした。それから、そもそも<a class="keyword" href="http://d.hatena.ne.jp/keyword/macOS">macOS</a>でヒットした2つのエラーはどちらも出所は自作の<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%D7%A5%E9%A5%B0%A5%A4%A5%F3">プラグイン</a>っぽい感じだったが、いろいろ調べたところ自作すべき理由がもうなさそうだったので、それらは使わなくて済むようにした。</p> <h3>Shougo/neobundle.<a class="keyword" href="http://d.hatena.ne.jp/keyword/vim">vim</a></h3> <p>最初にneobundle.<a class="keyword" href="http://d.hatena.ne.jp/keyword/vim">vim</a>を後継の<a href="https://github.com/Shougo/dein.vim">dein.vim</a>に移行した。設定はNeoBundleみたいに<a class="keyword" href="http://d.hatena.ne.jp/keyword/Vim">Vim</a> Scriptで書くこともできるが、TOMLで定義することもでき、僕はTOMLを使うことにした。neobundle.<a class="keyword" href="http://d.hatena.ne.jp/keyword/vim">vim</a>は2018年でメンテが止まっていて、かつdein.<a class="keyword" href="http://d.hatena.ne.jp/keyword/vim">vim</a>の方が速いらしい。</p> <h3>Shougo/unite.<a class="keyword" href="http://d.hatena.ne.jp/keyword/vim">vim</a></h3> <p>後継の<a href="https://github.com/Shougo/denite.nvim">denite.nvim</a>にしようとしたのだが、2014年のUnite.<a class="keyword" href="http://d.hatena.ne.jp/keyword/vim">vim</a>とはあまりにも挙動が違いすぎる上、結構時間を使っていろいろ調べたがなかなか自分の期待通り動くように設定できなかったので、一旦これに移行するのは先送りにすることにした。</p> <p><a href="https://github.com/junegunn/fzf.vim">fzf.vim</a> というのも一瞬試してみたけど、denite.nvimよりも更に期待から離れる挙動だったのでこれも保留にした。思ってたよりファンシーなUI。</p> <p>諦めてunite.<a class="keyword" href="http://d.hatena.ne.jp/keyword/vim">vim</a>のバージョンを2014年のものから最新のものに更新して一旦凌ぐ方針に変えた。そもそもneobundle.<a class="keyword" href="http://d.hatena.ne.jp/keyword/vim">vim</a>と違ってunite.<a class="keyword" href="http://d.hatena.ne.jp/keyword/vim">vim</a>はバグフィクスの範囲で現在もメンテが継続しているため、古いバージョンに固定などしていなければ、ある日突然壊れるリスクはneobundle.<a class="keyword" href="http://d.hatena.ne.jp/keyword/vim">vim</a>より低い感じがする。</p> <p>適当にmasterに更新してみたところ、見た目が自分が元々使っていたものと大分異なるため違和感がある状態だった。<a href="https://github.com/Shougo/unite.vim/issues/905">カーソル行ハイライトの挙動が変わった</a>のが原因だなとわかったが、パフォーマンスの都合により、これは戻されることはないらしい。元のハイライト方法がシェルで愛用している<a href="https://github.com/peco/peco">peco</a>のそれと一緒だったのが気にいっていたので、どうにかして戻したかったので、forkして<a href="https://github.com/k0kubun/unite.vim/commit/389cc2019dd926e9552a914724135a2e234226ab">リバースバックポート</a>した。まあ2014年のものに固定し続けるよりforkの運用の方がマシとはいえ、本質的には何の解決にもなってないので、そのうちdenite.nvimに移行する予定。</p> <h3>Shougo/neocomplete.<a class="keyword" href="http://d.hatena.ne.jp/keyword/vim">vim</a></h3> <p>後継の<a href="https://github.com/Shougo/deoplete.nvim">deoplete.nvim</a>に移行。設定のインターフェースがneocompleteそのままっぽい感じだったので移行は一瞬でできた。</p> <h3>k0kubun/<a class="keyword" href="http://d.hatena.ne.jp/keyword/vim">vim</a>-open-<a class="keyword" href="http://d.hatena.ne.jp/keyword/github">github</a></h3> <p><a class="keyword" href="http://d.hatena.ne.jp/keyword/Vim">Vim</a>で開いているファイルの<a class="keyword" href="http://d.hatena.ne.jp/keyword/GitHub">GitHub</a> URLをブラウザで開く奴。元々<a href="tonchis/vim-to-github">tonchis/vim-to-github</a>にPRを送りつつ使っていたのが、<a class="keyword" href="http://d.hatena.ne.jp/keyword/GitHub">GitHub</a> Enterpriseに対応させたりなどのために自分で書き直したのだった。で、これがif_<a class="keyword" href="http://d.hatena.ne.jp/keyword/ruby">ruby</a>を使っていて、<a class="keyword" href="http://d.hatena.ne.jp/keyword/Vim">Vim</a>をインストールするとif_python3が有効なことは多いがif_<a class="keyword" href="http://d.hatena.ne.jp/keyword/ruby">ruby</a>は大体ついてなくて面倒なので、この<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%D7%A5%E9%A5%B0%A5%A4%A5%F3">プラグイン</a>は捨てたいなと思っていた。</p> <p><a href="https://github.com/tyru/open-browser-github.vim">tyru/open-browser-github.vim</a> がよく使われていてメンテもされてそうだったので、これに移行することにした。OpenGithubFile 以外にもOpenなんとかコマンドがいっぱい定義されるせいで <code>:Op&lt;Tab&gt;</code> で一発で補完できないのが不便だなと思ったけど、使わないやつをdelfunctionとdelcommandしていくことで解決できた。</p> <h3>k0kubun/unite-git_files</h3> <p>Git<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%EA%A5%DD%A5%B8%A5%C8%A5%EA">リポジトリ</a>内では <code>git ls-files</code> を使い、それ以外の場所では file_rec を使うUniteソース。元々<a href="https://github.com/yuku/unite-git">yuku/unite-git</a>に高速化のために<a class="keyword" href="http://d.hatena.ne.jp/keyword/Lua">Lua</a>対応のPRなども送りつつ使っていたが、多分 file_rec へのフォールバック部分が欲しくてforkした。<a class="keyword" href="http://d.hatena.ne.jp/keyword/Lua">Lua</a>がなければ<a class="keyword" href="http://d.hatena.ne.jp/keyword/Vim">Vim</a> Scriptで動くようにしたとはいえ、この<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%D7%A5%E9%A5%B0%A5%A4%A5%F3">プラグイン</a>のためにif_<a class="keyword" href="http://d.hatena.ne.jp/keyword/lua">lua</a>に気を使わないといけないのもちょっとなあ、と思っていた。</p> <p>で、これは<a href="https://github.com/Shougo/denite.nvim/blob/4eb4327162c4ec885446b349149b5d25b7307bc7/doc/denite.txt#L1988-L1989">denite.nvimのドキュメント</a>で推奨されている <code>finddir('.git', ';') != '' ? 'file/rec/git' : 'file/rec'</code> がUniteでも同じ感じで設定できるので、この<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%D7%A5%E9%A5%B0%A5%A4%A5%F3">プラグイン</a>も不要になった。<code>finddir('.git', ';')</code> だとGit<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%EA%A5%DD%A5%B8%A5%C8%A5%EA">リポジトリ</a>トップじゃないと期待通り動かないんじゃないかと心配だったが、それは杞憂だった。</p> <p>追記: ファイルが多いと file_rec/git が結構遅いことに気付いた。<a class="keyword" href="http://d.hatena.ne.jp/keyword/Lua">Lua</a>なしなら最新のUnite.<a class="keyword" href="http://d.hatena.ne.jp/keyword/vim">vim</a>とNeoVimで問題なくこの<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%D7%A5%E9%A5%B0%A5%A4%A5%F3">プラグイン</a>が動くし、別に<a class="keyword" href="http://d.hatena.ne.jp/keyword/Lua">Lua</a>なしでも file_rec/git よりは大分速いという感じだったので、ひとまずこの<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%D7%A5%E9%A5%B0%A5%A4%A5%F3">プラグイン</a>の利用は継続することにした。</p> <h2>Language Server Protocol</h2> <p>あとは使ってそうな設定を持ってきて整理するだけで大体準備できたけど、NeoVimも特に<a class="keyword" href="http://d.hatena.ne.jp/keyword/Vim">Vim</a>と変わった感じしないし、Uniteも無理やり元の挙動に合わせたことで何も変わり映えしなくてつまらんなという感じがしたので、気になっていたLSP連携<a href="#f-bbf73310" name="fn-bbf73310" title="どんなエディタでもLanguage Server Protocolに対応することで、それを実装しているサーバーと連携すればIDE的な機能が使える、というもの">*2</a>を試すことにした。</p> <p>deoplete.nvim に移行したことで、どうやら <a href="https://github.com/lighttiger2505/deoplete-vim-lsp">deoplete-vim-lsp</a> と <a href="https://github.com/prabirshrestha/vim-lsp">vim-lsp</a> をいれるだけでLSP連携が動くらしいと <a href="https://twitter.com/giginet">@giginet</a> 先輩に教えてもらった。</p> <p>deoplete-<a class="keyword" href="http://d.hatena.ne.jp/keyword/vim">vim</a>-lsp のREADMEにあったGoの例を試そうとしたが、そこにあったbingoはgolspがあるのでメンテが停止していたとのことだったので、<a href="https://mattn.kaoriya.net/software/lang/go/20181217000056.htm">mattnさんの記事</a>を参考にgopls<a href="#f-503715b5" name="fn-503715b5" title="ていうか、golspからgoplsに名前変わった…?">*3</a>を試した。なんか型に応じて補完されたり、使われてない変数がハイライトされたりとか、<a class="keyword" href="http://d.hatena.ne.jp/keyword/IDE">IDE</a>っぽい感じに使えて面白かった。</p> <p>まあ、<a class="keyword" href="http://d.hatena.ne.jp/keyword/IDE">IDE</a>みたいに起動してから長い時間インデックスに待たされることもなく、インデックス用のバックグラウンドプロセスが壊れるのを直したりするのに時間を使わされることなくスイスイ書き始めたい時に<a class="keyword" href="http://d.hatena.ne.jp/keyword/Vim">Vim</a>を使っているみたいなところもあるので、実際<a class="keyword" href="http://d.hatena.ne.jp/keyword/Vim">Vim</a>でLSP使いたいかどうかはまた別の話なんだけど。</p> <h2>最近のタイムラインに関する余談</h2> <p><blockquote data-conversation="none" class="twitter-tweet" data-lang="en"><p lang="ja" dir="ltr">今は<a class="keyword" href="http://d.hatena.ne.jp/keyword/emacs">emacs</a>が滅んで<a class="keyword" href="http://d.hatena.ne.jp/keyword/vim">vim</a>が生き残ったのは誰の目にも明らかだけど、これは自分には結構驚きなんだよな。</p>&mdash; karino2@平民階級 (@karino2012) <a href="https://twitter.com/karino2012/status/1365459160398061573?ref_src=twsrc%5Etfw">February 27, 2021</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script> </p> <p>冒頭に昔<a class="keyword" href="http://d.hatena.ne.jp/keyword/Emacs">Emacs</a>やめて<a class="keyword" href="http://d.hatena.ne.jp/keyword/Vim">Vim</a>に移った話を書きはしたが、<a class="keyword" href="http://d.hatena.ne.jp/keyword/Emacs">Emacs</a>が滅んだと思ったことはなかったので、いつのまにかそういう風潮になっていることに驚いた。同僚や同世代に<a class="keyword" href="http://d.hatena.ne.jp/keyword/Emacs">Emacs</a>を使っている人は今でもいっぱいいる<a href="#f-c9089793" name="fn-c9089793" title="単に自分がもう若者ではなくなってしまったからだとは思うが">*4</a>し、<a class="keyword" href="http://d.hatena.ne.jp/keyword/Emacs">Emacs</a>を使ってることで知られている僕が尊敬する人たちも今でも<a class="keyword" href="http://d.hatena.ne.jp/keyword/Emacs">Emacs</a>を使っていそう、というくらいの認識だった。<a class="keyword" href="http://d.hatena.ne.jp/keyword/Lisp">Lisp</a><a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%CF%A5%C3%A5%AB%A1%BC">ハッカー</a>の<a href="https://twitter.com/anohana/status/1365553784429060099">Paul Grahamが (Lispで設定できるEmacsではなく) vi使いらしい</a>という話が出てたのはちょっと面白かった。</p> <p><blockquote data-conversation="none" class="twitter-tweet" data-lang="en"><p lang="ja" dir="ltr"><a class="keyword" href="http://d.hatena.ne.jp/keyword/vim">vim</a>-jp に入らないのはそもそも<a class="keyword" href="http://d.hatena.ne.jp/keyword/vim">vim</a>使ってないこと以前に、内輪ノリ感が強すぎてウッとなるからです</p>&mdash; <a class="keyword" href="http://d.hatena.ne.jp/keyword/OSS">OSS</a>タダ乗りおじさん (@mizchi) <a href="https://twitter.com/mizchi/status/1366605026097917952?ref_src=twsrc%5Etfw">March 2, 2021</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script> </p> <p>僕はこれまで<a class="keyword" href="http://d.hatena.ne.jp/keyword/vim">vim</a>-jpに入ってなくて雰囲気を知らなかったのでこの内容に関しては<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%CB%A5%E5%A1%BC%A5%C8%A5%E9">ニュートラ</a>ルなんだけど、ちょうどvimrc書き直してるところにこれが流れてきて質問とかするのに便利そうだなと思って<a class="keyword" href="http://d.hatena.ne.jp/keyword/vim">vim</a>-jp Slackに入り、「mizchiさんのツイートを見て<a class="keyword" href="http://d.hatena.ne.jp/keyword/vim">vim</a>-jp Slackにジョインしました」というボケを<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A4%AB%A4%DE%A4%B7">かまし</a>たら<a href="https://vim-jp.org/slacklog/C03C4RC9F/2021/03/#ts-1614662916.181100">このツイートでちょっと盛り上がっていた</a>。</p> <div class="footnote"> <p class="footnote"><a href="#fn-d838a2ce" name="f-d838a2ce" class="footnote-number">*1</a><span class="footnote-delimiter">:</span><span class="footnote-text"><a class="keyword" href="http://d.hatena.ne.jp/keyword/Vim">Vim</a> 8.2が<a class="keyword" href="http://d.hatena.ne.jp/keyword/Lua">Lua</a>に互換性がなくなったことによるもので、unite.<a class="keyword" href="http://d.hatena.ne.jp/keyword/vim">vim</a>最新版では修正済みとのことです <a href="https://twitter.com/ShougoMatsu/status/1367281209638674432">https://twitter.com/ShougoMatsu/status/1367281209638674432</a></span></p> <p class="footnote"><a href="#fn-bbf73310" name="f-bbf73310" class="footnote-number">*2</a><span class="footnote-delimiter">:</span><span class="footnote-text">どんなエディタでもLanguage Server Protocolに対応することで、それを実装しているサーバーと連携すれば<a class="keyword" href="http://d.hatena.ne.jp/keyword/IDE">IDE</a>的な機能が使える、というもの</span></p> <p class="footnote"><a href="#fn-503715b5" name="f-503715b5" class="footnote-number">*3</a><span class="footnote-delimiter">:</span><span class="footnote-text">ていうか、golspからgoplsに名前変わった…?</span></p> <p class="footnote"><a href="#fn-c9089793" name="f-c9089793" class="footnote-number">*4</a><span class="footnote-delimiter">:</span><span class="footnote-text">単に自分がもう若者ではなくなってしまったからだとは思うが</span></p> </div> k0kubun RyzenでPCを組み直したら爆速で最高になった hatenablog://entry/26006613678623986 2021-01-15T17:19:48+09:00 2021-01-15T17:20:20+09:00 5年半前に組んだIntel Core i7-4790Kのマシンが結構速くて快適だなあと思いながら日々を過ごしていたが、僕のCPUだと遅くなるけどRyzenだと速くなる状況に遭遇したり、PassMarkで元のCPUより大分速くて趣味の開発の生産性への寄与が大きそうだったので、今日CPUをRyzen 7 5800Xに取り替えた。 どのくらい速くなったのか そもそも何故速いマシンが欲しいかというと、普段の生活でRubyのJITのシングルスレッド性能を測りまくっていて、そのベンチが速く走るほど結果の解像度が上がり、速くなったかの判定がしやすくなるというモチベーションがあった。そういうわけで実際よく走ら… <p><a href="https://k0kubun.hatenablog.com/entry/2015/08/16/162142">5年半前に組んだIntel Core i7-4790Kのマシン</a>が結構速くて快適だなあと思いながら日々を過ごしていたが、<a href="https://github.com/ruby/ruby/pull/3793#issuecomment-737347823">僕のCPUだと遅くなるけどRyzenだと速くなる状況</a>に遭遇したり、<a href="https://www.cpubenchmark.net/singleThread.html">PassMark</a>で元のCPUより大分速くて趣味の開発の生産性への寄与が大きそうだったので、今日CPUを<a class="keyword" href="http://d.hatena.ne.jp/keyword/Ryzen">Ryzen</a> 7 5800Xに取り替えた。</p> <p><span itemscope itemtype="http://schema.org/Photograph"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/k/k0kubun/20210115/20210115155350.jpg" alt="f:id:k0kubun:20210115155350j:plain" title="" class="hatena-fotolife" itemprop="image"></span></p> <h1>どのくらい速くなったのか</h1> <p>そもそも何故速いマシンが欲しいかというと、普段の生活で<a class="keyword" href="http://d.hatena.ne.jp/keyword/Ruby">Ruby</a>の<a class="keyword" href="http://d.hatena.ne.jp/keyword/JIT">JIT</a>のシングルスレッド性能を測りまくっていて、そのベンチが速く走るほど結果の解像度が上がり、速くなったかの判定がしやすくなるというモチベーションがあった。そういうわけで実際<a href="https://github.com/mame/optcarrot">よく走らせてるRubyのベンチ</a>の<a class="keyword" href="http://d.hatena.ne.jp/keyword/Ruby">Ruby</a> 3.0 <a class="keyword" href="http://d.hatena.ne.jp/keyword/JIT">JIT</a>時のピーク性能 <a href="#f-cb69ba53" name="fn-cb69ba53" title="--frames=3000 のこと https://github.com/mame/optcarrot/pull/26#issuecomment-734023613">*1</a>を比較したら以下のようになった。<a href="#f-bbef0919" name="fn-bbef0919" title="ベンチマーク環境の詳細はこちら https://gist.github.com/k0kubun/b787f4466324f0551557c1986a5213ee">*2</a></p> <table> <thead> <tr> <th style="text-align:left;"> <a class="keyword" href="http://d.hatena.ne.jp/keyword/Core%20i7">Core i7</a>-4790K </th> <th style="text-align:left;"> <a class="keyword" href="http://d.hatena.ne.jp/keyword/Ryzen">Ryzen</a> 7 5800X </th> </tr> </thead> <tbody> <tr> <td style="text-align:left;"> 106.11fps </td> <td style="text-align:left;"> 142.09fps </td> </tr> </tbody> </table> <p><strong>1.34倍</strong>速い。ていうか、<a href="https://twitter.com/k0kubun/status/971014403851079681">JITでも60fpsくらいしか出ない時</a>からこの<a class="keyword" href="http://d.hatena.ne.jp/keyword/fps">fps</a>を2~3上げるような改善をめっちゃ繰り返してたので、142fpsが見れるのは、マジかーという感じ。</p> <h1>最速のシングルスレッドCPU</h1> <p><a class="keyword" href="http://d.hatena.ne.jp/keyword/Ryzen">Ryzen</a> 7 5800Xは<a href="https://www.cpubenchmark.net/singleThread.html">シングルスレッド性能のPassMark</a>でつい最近まで最速<em>だった</em>。<a class="keyword" href="http://d.hatena.ne.jp/keyword/Intel">Intel</a> i9-10900Kとは結構差が開いてたけど、未発売の<a class="keyword" href="http://d.hatena.ne.jp/keyword/Intel">Intel</a> 第11世代 Rocket Lakeのi7-11700Kのスコアが最近提出されており、どうやら<a class="keyword" href="http://d.hatena.ne.jp/keyword/Ryzen">Ryzen</a> 5000シリーズより若干速いらしい。<a class="keyword" href="http://d.hatena.ne.jp/keyword/Ryzen">Ryzen</a>の影響で<a class="keyword" href="http://d.hatena.ne.jp/keyword/Intel">Intel</a>も値段下がるらしいけど、$449 で買って現時点で最速なので、<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%B3%A5%B9%A5%D1">コスパ</a>的には悪くなかったかなと思っている。</p> <p><span itemscope itemtype="http://schema.org/Photograph"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/k/k0kubun/20210115/20210115161611.png" alt="f:id:k0kubun:20210115161611p:plain" title="" class="hatena-fotolife" itemprop="image"></span></p> <p>ちなみにi7-4790Kの結果も同じページにあるけど、2,468なので、1.42倍速いことになる。<a class="keyword" href="http://d.hatena.ne.jp/keyword/Ruby">Ruby</a>の<a class="keyword" href="http://d.hatena.ne.jp/keyword/JIT">JIT</a>のベンチの比ともそれほど外れておらず、なかなか参考になるベンチだと思う。</p> <h1>買ったパーツ</h1> <p>ここからは余談だけど、単にCPUを<a class="keyword" href="http://d.hatena.ne.jp/keyword/Ryzen">Ryzen</a>にしたいだけだったのに他に買わないといけないパーツが4つもあったので、最速のCPUが欲しい人向けに購入にあたっての知見などを書いておく。僕はゲームはしないのでどれも開発時の性能を犠牲にしない範囲で最も安いものを選んだつもり。</p> <h2>CPU: <a class="keyword" href="http://d.hatena.ne.jp/keyword/Ryzen">Ryzen</a> 7 5800X</h2> <p>上のグラフや<a class="keyword" href="http://d.hatena.ne.jp/keyword/TDP">TDP</a>からもわかる通り、<a class="keyword" href="http://d.hatena.ne.jp/keyword/Ryzen">Ryzen</a> 5000シリーズの中で<a class="keyword" href="http://d.hatena.ne.jp/keyword/Ryzen">Ryzen</a> 5 5600Xだけは若干遅く、他はシングルスレッド性能では大体同じみたいな感じになっている。お金は節約したいし5600Xの<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%B3%A5%B9%A5%D1">コスパ</a>はすごいけど、できるなら最速クラスの奴がいいし、キリよく8コア16スレッド欲しいなということで5800Xになった。</p> <p>あと、日本の<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%AA%A5%F3%A5%E9%A5%A4%A5%F3%A5%B9%A5%C8%A5%A2">オンラインストア</a>ではたまに<a class="keyword" href="http://d.hatena.ne.jp/keyword/Twitter">Twitter</a>検索するだけで5900Xとかでも普通に在庫が見つかる状態だったのが、USのストアでは定価だとどれも在庫の確保が困難で、かつ実質5600Xか5800Xしか手に入らない状態だった。リングフィットアド<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%D9%A5%F3%A5%C1%A5%E3%A1%BC">ベンチャー</a>買う時に在庫監視の経験を積んでいたのでどうにか欲しいものを確保でき<a href="#f-84b24a6c" name="fn-84b24a6c" title="amazon.com のRyzenをカートにいれるページをリロードしすぎてそこから24時間犬の画像の503が返り続けたこともあった。Prime会員なのに…">*3</a>、Preorderから配達までは2週間かかって今日に至る。</p> <h2>CPUクーラー: Noctua NH-D15S</h2> <p><a class="keyword" href="http://d.hatena.ne.jp/keyword/Ryzen">Ryzen</a> 5600Xより<a class="keyword" href="http://d.hatena.ne.jp/keyword/TDP">TDP</a>が高いということはすなわち高い冷却性能が要求されるということで、5800X以上ではCPUクーラーが付属しておらず、これも5600Xの<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%B3%A5%B9%A5%D1">コスパ</a>の一部になっている。<a class="keyword" href="http://d.hatena.ne.jp/keyword/Ryzen">Ryzen</a>買った人は水冷をやっている人が多い気がするけど、空冷より寿命が短いらしいので空冷にした。これめちゃくちゃでかいんだけど、でかい方が<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%D2%A1%BC%A5%C8%A5%B7%A5%F3%A5%AF">ヒートシンク</a>による冷却性能が高くファンの回転数をおさえられて静音らしいのと、当然性能にも影響するので、ケースに入りそうな範囲ででかい奴にした。いろいろ取り回しが大変になった。</p> <h2><a class="keyword" href="http://d.hatena.ne.jp/keyword/GPU">GPU</a>: <a class="keyword" href="http://d.hatena.ne.jp/keyword/GeForce">GeForce</a> GT 1030 (<a class="keyword" href="http://d.hatena.ne.jp/keyword/Gigabyte">Gigabyte</a> GV-N1030OC-2GI)</h2> <p><a class="keyword" href="http://d.hatena.ne.jp/keyword/Ryzen">Ryzen</a>のXシリーズは、<a class="keyword" href="http://d.hatena.ne.jp/keyword/Radeon">Radeon</a> Graphicsが内蔵される<a class="keyword" href="http://d.hatena.ne.jp/keyword/Ryzen">Ryzen</a> Gシリーズと違い、仮に<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%DE%A5%B6%A5%DC">マザボ</a>に<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%AA%A5%F3%A5%DC%A1%BC%A5%C9">オンボード</a>グラフィックがあってもそこから映像を出力することができない。CPU内蔵の<a class="keyword" href="http://d.hatena.ne.jp/keyword/Intel">Intel</a> HD Graphicsに依存してきたので、今回<a class="keyword" href="http://d.hatena.ne.jp/keyword/GPU">GPU</a>を買わなければならなかった。</p> <p><a class="keyword" href="http://d.hatena.ne.jp/keyword/Ryzen">Ryzen</a> 5000シリーズを買ってる人は大体ゲーマーなので普通RTXとペアにすると思うんだけど、まあターミナルしか動かさないので、GTXですらなくGTシリーズを買うことにした。最初はGT 710のボードを買ったんだけど、4K出力のせいで見てわかる程度に処理がカクカクになったので、それより若干高いが性能はかなり勝るGT 1030を使うことにした。見出しに書いたのは<a class="keyword" href="http://d.hatena.ne.jp/keyword/HDMI">HDMI</a> 4K@60fpsができるボードなんだけど、使ってるディスプレイがどの道<a class="keyword" href="http://d.hatena.ne.jp/keyword/HDMI">HDMI</a> 4K@30fpsまでしか対応してないことに気づいたのと、あとやっぱ静音にしたいなという気持ちになったので、パッシブ冷却の<a class="keyword" href="http://d.hatena.ne.jp/keyword/Asus">Asus</a>のGT 1030ボードに変える予定。</p> <h2><a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%DE%A5%B6%A5%DC">マザボ</a>: <a class="keyword" href="http://d.hatena.ne.jp/keyword/Gigabyte">Gigabyte</a> A520 AORUS Elite</h2> <p>CPUソケットが変わるので、まあこれを買い替えないといけないのはしょうがない。<a class="keyword" href="http://d.hatena.ne.jp/keyword/Ryzen">Ryzen</a> 5000シリーズに公式に対応している<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%C1%A5%C3%A5%D7%A5%BB%A5%C3%A5%C8">チップセット</a>はX570、B550、A520があり、A520が一番安い。<a class="keyword" href="http://d.hatena.ne.jp/keyword/A320">A320</a>でもASRockが<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%D5%A5%A1%A1%BC%A5%E0%A5%A6%A5%A7%A5%A2">ファームウェア</a>新しくすることで対応させたボードもあるけど、RAMが2レーンしかないのが気になってスキップ。A520はPCIe 4.0が使えないのがネックだけど、どうせ繋ぐのがGT 1030ならどうでもいいので、このボードに大変満足している。調べてて思ったけど、そのうち<a class="keyword" href="http://d.hatena.ne.jp/keyword/SSD">SSD</a>はNVMeにしたいなと思った。</p> <h2>RAM: Crucial CT16G4DFD8266 (16GB x 1)</h2> <p><a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%DE%A5%B6%A5%DC">マザボ</a>が5年も新しくなるのRAMの世代がDDR3からDDR4に変わってしまい、これには<a class="keyword" href="http://d.hatena.ne.jp/keyword/%B8%E5%CA%FD%B8%DF%B4%B9">後方互換</a>性がないのでこれも買い替えることになる。まあDDR4のRAMは<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%DE%A5%B6%A5%DC">マザボ</a>よりは今後使い回しが効く気がするので別に良い。</p> <p><a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%DE%A5%B6%A5%DC">マザボ</a>がサポートしてる範囲は結構あるけど、動かないと怖いので<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%DE%A5%B6%A5%DC">マザボ</a>のサポートページで公式にサポートされてる奴の中から選び、値段が控え目な2666MHzの奴にした。<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%DE%A5%B6%A5%DC">マザボ</a>的には32GB x 4までいけるんだけど、まあ多くても16GB x 4 = 64GBでいいかなと思ったのと、とりあえず元の16GBに揃えて安く済ませたかったので、一旦16GBの奴を1枚買った。そのうち32GBとかにはしようと思っている。</p> <h1>まとめ</h1> <p>追加でいろいろ買い替えないといけないのが嫌でこれまで渋ってたけど、買ってみると期待通り速くて満足した。</p> <div class="footnote"> <p class="footnote"><a href="#fn-cb69ba53" name="f-cb69ba53" class="footnote-number">*1</a><span class="footnote-delimiter">:</span><span class="footnote-text">--frames=3000 のこと <a href="https://github.com/mame/optcarrot/pull/26#issuecomment-734023613">https://github.com/mame/optcarrot/pull/26#issuecomment-734023613</a></span></p> <p class="footnote"><a href="#fn-bbef0919" name="f-bbef0919" class="footnote-number">*2</a><span class="footnote-delimiter">:</span><span class="footnote-text"><a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%D9%A5%F3%A5%C1%A5%DE%A1%BC%A5%AF">ベンチマーク</a>環境の詳細はこちら <a href="https://gist.github.com/k0kubun/b787f4466324f0551557c1986a5213ee">https://gist.github.com/k0kubun/b787f4466324f0551557c1986a5213ee</a></span></p> <p class="footnote"><a href="#fn-84b24a6c" name="f-84b24a6c" class="footnote-number">*3</a><span class="footnote-delimiter">:</span><span class="footnote-text"><a class="keyword" href="http://d.hatena.ne.jp/keyword/amazon.com">amazon.com</a> の<a class="keyword" href="http://d.hatena.ne.jp/keyword/Ryzen">Ryzen</a>をカートにいれるページをリロードしすぎてそこから24時間犬の画像の503が返り続けたこともあった。Prime会員なのに…</span></p> </div> k0kubun 2020年にやったこと hatenablog://entry/26006613672292250 2020-12-31T14:02:47+09:00 2020-12-31T14:07:07+09:00 2019年にやったこと 2018年にやったこと 2017年にやったこと 2016年にやったこと 2015年にやったこと ハイライト 子供が産まれた 大学院生になった Ruby 3x3 を達成した I became a father ☺️ pic.twitter.com/Uq0Jgbduny— k0kubun (@k0kubun) July 15, 2020 I've been officially admitted to Georgia Tech's OMSCS (Online Master of Computer Science). I'm excited for being a stude… <ul> <li><a href="https://k0kubun.hatenablog.com/entry/2019-summary">2019年にやったこと</a></li> <li><a href="https://k0kubun.hatenablog.com/entry/2018-summary">2018年にやったこと</a></li> <li><a href="https://k0kubun.hatenablog.com/entry/2017-summary">2017年にやったこと</a></li> <li><a href="https://k0kubun.hatenablog.com/entry/2016-summary">2016年にやったこと</a></li> <li><a href="https://k0kubun.hatenablog.com/entry/2015/12/31/000052">2015年にやったこと</a></li> </ul> <h1>ハイライト</h1> <ul> <li>子供が産まれた</li> <li>大学院生になった</li> <li><a class="keyword" href="http://d.hatena.ne.jp/keyword/Ruby">Ruby</a> <a class="keyword" href="http://d.hatena.ne.jp/keyword/3x3">3x3</a> を達成した</li> </ul> <p><blockquote data-conversation="none" class="twitter-tweet" data-lang="en"><p lang="en" dir="ltr">I became a father ☺️ <a href="https://t.co/Uq0Jgbduny">pic.twitter.com/Uq0Jgbduny</a></p>&mdash; k0kubun (@k0kubun) <a href="https://twitter.com/k0kubun/status/1283503556578795520?ref_src=twsrc%5Etfw">July 15, 2020</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script> </p> <p><blockquote data-conversation="none" class="twitter-tweet" data-lang="en"><p lang="en" dir="ltr">I&#39;ve been officially admitted to <a class="keyword" href="http://d.hatena.ne.jp/keyword/Georgia">Georgia</a> Tech&#39;s OMSCS (Online Master of Computer Science). I&#39;m excited for being a student again. I chose the online course to take it without quitting my job, but due to COVID-19 it&#39;s probably not that different from other people&#39;s experience.</p>&mdash; k0kubun (@k0kubun) <a href="https://twitter.com/k0kubun/status/1289318913730179072?ref_src=twsrc%5Etfw">July 31, 2020</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script> </p> <p><blockquote data-conversation="none" class="twitter-tweet" data-lang="en"><p lang="en" dir="ltr">As promised, we&#39;ve delivered the 3x faster <a class="keyword" href="http://d.hatena.ne.jp/keyword/Ruby">Ruby</a> 3.0 💪 <a href="https://t.co/1RyyvEE9UY">https://t.co/1RyyvEE9UY</a></p>&mdash; k0kubun (@k0kubun) <a href="https://twitter.com/k0kubun/status/1342351686178762762?ref_src=twsrc%5Etfw">December 25, 2020</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script> </p> <p>全てが妻の大きな助けがなければ有り得なかった。すごく感謝している。</p> <h1>発表</h1> <p>子供ができる前に発表か録画ができないものは基本的に応募もしなかったし誘われても断わっていた <a href="#f-d28b918b" name="fn-d28b918b" title="なのでRubyKaigiもCFP通ってたけどTakeoutには登壇しなかった">*1</a> ので例年より数が少ない。幸運にもそれ以前にお声がけいただいたところで登壇させていただいた。</p> <ul> <li><a class="keyword" href="http://d.hatena.ne.jp/keyword/Ruby">Ruby</a> 3 さみっと: <a href="https://speakerdeck.com/k0kubun/ruby-3-samituto">JIT ロードマップ</a></li> <li>銀座<a class="keyword" href="http://d.hatena.ne.jp/keyword/Rails">Rails</a>#23: <a href="https://speakerdeck.com/k0kubun/ruby-3-dot-0-jit-on-rails">Ruby 3.0 JIT on Rails</a></li> <li>RubyConf China 2020: <a href="https://speakerdeck.com/k0kubun/rubyconf-china-2020">Ruby 3 JIT's roadmap</a></li> </ul> <p>毎回新ネタをいれてるつもりではあるものの、ここ数年ほとんど<a class="keyword" href="http://d.hatena.ne.jp/keyword/Ruby">Ruby</a>の<a class="keyword" href="http://d.hatena.ne.jp/keyword/JIT">JIT</a>の話しかしていない…。ちなみにRubyConf Chinaは初の<a class="keyword" href="http://d.hatena.ne.jp/keyword/Keynote">Keynote</a>枠でのお誘いだった。コロナな分スピーカー集めるの大変そうだったのと、オンラインなのであまり違いを感じなかったというのはあったけど。</p> <h1>仕事</h1> <p><a href="https://k0kubun.hatenablog.com/entry/2019-summary">去年</a>書いたサービスの切り出しが一区切りついて、それを活用して新プロジェクトが1つ以上効率的に進められていた感じがするのでよかった。切り出しの完全な終了が終わらないと各所に負担がかかるもののプライオリティが下げられているというのが残念ポイント。</p> <p>育休後の後半は他の人が二人でやっていたその新プロジェクトに数名と僕が加わりつつチーム内でのリードを僕がやっていた。入社してからいつも一人でいろんなチームの<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%EA%A5%DD%A5%B8%A5%C8%A5%EA">リポジトリ</a>に自分でコードを書いて解決しにいくということが多かったが、そういうムーヴをしているとどんなにいい仕事をしても評価されにくく、実際会社への<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%A4%A5%F3%A5%D1%A5%AF">インパク</a>トがスケールしないのも事実なので、重要なものに集中しつつ協調作業もしやすいようにうまく<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%DE%A5%A4%A5%EB%A5%B9%A5%C8%A1%BC%A5%F3">マイルストーン</a>を切ったり、自分が得意なタスクを自分が消化し続けるのではなく他の人もできるようにするのを意識して働くように変わった。</p> <h1>US生活</h1> <p>コロナなのでかなり長い間ロックダウンされていた。普通に店内での外食や映画館やゲーセンがやってるらしい日本はすごい。家族と過ごす時間や趣味の開発以外の唯一の楽しみであるタピオカドリンクをほぼ毎日飲んでいる。あとは大体だっこ紐で散歩。</p> <p>コロナの影響でトランプが<a href="https://seattle-life.hatenablog.com/entry/2020/06/23/143515">ビザでの入国を困難にした</a>関係で、現時点では一応可能ではあるものの再入国のリスクがかなり高くなってしまったので、僕は今年は日本に一秒もいなかった。<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%D9%A5%A4%A5%A8%A5%EA%A5%A2">ベイエリア</a>には治安が最悪のところにしか<a class="keyword" href="http://d.hatena.ne.jp/keyword/%B2%BB%A5%B2%A1%BC">音ゲー</a>が置いてあるゲーセンがないので、毎シリーズSP八段だけはとりあえず受け直している<a class="keyword" href="http://d.hatena.ne.jp/keyword/%B2%BB%A5%B2%A1%BC">音ゲー</a>もやっていない。</p> <p>生活の基盤整備が落ち着いた夏ごろからUSでの資産運用をやり始めた。いまだに資産の大部分は日本円でそっちはもう動かせないんだけど、USDの運用だけで毎月平均10万円相当の利益がでており、そのままのペースで老後まで行って欲しい。</p> <p>あと、会社のご厚意で渡米後すぐ始めていた<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%B0%A5%EA%A1%BC%A5%F3%A5%AB%A1%BC%A5%C9">グリーンカード</a>申請の準備が終わり、やっと今月申請が始められた。EB-3なんだけど、運が良ければここから1年半くらいで終わりそうだが、コロナな上に<a href="https://www.natlawreview.com/article/long-awaited-green-card-bill-s386-clears-senate-approval">S.386</a>が通りそうなので取得までここから2年、最悪3年くらいは普通に覚悟している。</p> <h1>勉強</h1> <p>大学院入学に必要だった<a class="keyword" href="http://d.hatena.ne.jp/keyword/TOEFL">TOEFL</a> 100点が本当に大変だった。口頭で頻繁に英語を話すチームに入ってからもう3年弱経つが、いつまで経っても英語わからんなあという気持ち。実用上はリスニングが一番苦手で、スピーキングはどちらかというと時間を投資できているつもりなのだが、試験を受けるとリスニングの点数が高くてスピーキングが低い。</p> <p><blockquote data-conversation="none" class="twitter-tweet" data-lang="en"><p lang="en" dir="ltr">I can do English!! 💪💪💪 (This is my first <a class="keyword" href="http://d.hatena.ne.jp/keyword/TOEFL">TOEFL</a> iBT score which exceeded 100) <a href="https://t.co/QRD2DVEPBZ">pic.twitter.com/QRD2DVEPBZ</a></p>&mdash; k0kubun (@k0kubun) <a href="https://twitter.com/k0kubun/status/1225665758778146816?ref_src=twsrc%5Etfw">February 7, 2020</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script> </p> <p><a class="keyword" href="http://d.hatena.ne.jp/keyword/TOEFL">TOEFL</a>試験勉強の間にリーディング速度の向上が感じられ <a href="#f-a6acefad" name="fn-a6acefad" title="というかTOEICでもそうなんだけど、リーディングがめちゃくちゃ遅くて解ききらないことが多かった">*2</a>、英文ライティングの型みたいなのを覚えて書く構成に自信が持てるようになったのはよかった。</p> <p>入学後も楽しくやっている。大体<a href="https://k0kubun.hatenablog.com/entry/omscs">前回の記事</a>に書いてその後は冬休みなので今はそれ以上書くことはない。</p> <h1>ブログ</h1> <p><a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%A2%A5%E1%A5%EA">アメリ</a>カ関係のブログを4つ<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A4%CF%A4%C6%A4%CA%A5%D6%A5%ED%A5%B0">はてなブログ</a>に書き、<a class="keyword" href="http://d.hatena.ne.jp/keyword/Ruby">Ruby</a> 3の話をMediumに、ほぼ自分向けの技術メモは8個Qiitaに書いた。</p> <ul> <li><a href="https://k0kubun.hatenablog.com/entry/bayarea-salary">&#x30D9;&#x30A4;&#x30A8;&#x30EA;&#x30A2;&#x306F;&#x6771;&#x4EAC;&#x3088;&#x308A;&#x5132;&#x304B;&#x308B;&#x306E;&#x304B; - k0kubun&#39;s blog</a><a href="https://b.hatena.ne.jp/entry/https://k0kubun.hatenablog.com/entry/bayarea-salary" class="http-bookmark"><img src="https://b.hatena.ne.jp/entry/image/https://k0kubun.hatenablog.com/entry/bayarea-salary" alt="" class="http-bookmark" /></a><img src="https://s.st-hatena.com/entry.count.image?uri=https%3A%2F%2Fk0kubun.hatenablog.com%2Fentry%2Fbayarea-salary" alt="" class="http-star" /></li> <li><a href="https://k0kubun.hatenablog.com/entry/omscs">&#x30EA;&#x30E2;&#x30FC;&#x30C8;&#x3067;&#x30A2;&#x30E1;&#x30EA;&#x30AB;&#x306E;&#x5927;&#x5B66;&#x9662;&#x306B;&#x901A;&#x3044;&#x59CB;&#x3081;&#x305F; - k0kubun&#39;s blog</a><a href="https://b.hatena.ne.jp/entry/https://k0kubun.hatenablog.com/entry/omscs" class="http-bookmark"><img src="https://b.hatena.ne.jp/entry/image/https://k0kubun.hatenablog.com/entry/omscs" alt="" class="http-bookmark" /></a><img src="https://s.st-hatena.com/entry.count.image?uri=https%3A%2F%2Fk0kubun.hatenablog.com%2Fentry%2Fomscs" alt="" class="http-star" /></li> <li><a href="https://k0kubun.hatenablog.com/entry/us-bootstrap">US&#x79FB;&#x4F4F;&#x3068;&#x30D6;&#x30FC;&#x30C8;&#x30B9;&#x30C8;&#x30E9;&#x30C3;&#x30D7;&#x554F;&#x984C; - k0kubun&#39;s blog</a><a href="https://b.hatena.ne.jp/entry/https://k0kubun.hatenablog.com/entry/us-bootstrap" class="http-bookmark"><img src="https://b.hatena.ne.jp/entry/image/https://k0kubun.hatenablog.com/entry/us-bootstrap" alt="" class="http-bookmark" /></a><img src="https://s.st-hatena.com/entry.count.image?uri=https%3A%2F%2Fk0kubun.hatenablog.com%2Fentry%2Fus-bootstrap" alt="" class="http-star" /></li> <li><a href="https://medium.com/@k0kubun/ruby-3-0-jit-and-beyond-4d9404ce33c">Ruby 3.0 JIT and beyond | by k0kubun | Dec, 2020 | Medium</a><a href="https://b.hatena.ne.jp/entry/https://medium.com/@k0kubun/ruby-3-0-jit-and-beyond-4d9404ce33c" class="http-bookmark"><img src="https://b.hatena.ne.jp/entry/image/https://medium.com/@k0kubun/ruby-3-0-jit-and-beyond-4d9404ce33c" alt="" class="http-bookmark" /></a></li> <li><a href="https://k0kubun.hatenablog.com/entry/us-investment">US&#x306E;&#x8CC7;&#x7523;&#x904B;&#x7528;&#x3068;&#x30AF;&#x30EC;&#x30B8;&#x30C3;&#x30C8;&#x30B9;&#x30B3;&#x30A2; - k0kubun&#39;s blog</a><a href="https://b.hatena.ne.jp/entry/https://k0kubun.hatenablog.com/entry/us-investment" class="http-bookmark"><img src="https://b.hatena.ne.jp/entry/image/https://k0kubun.hatenablog.com/entry/us-investment" alt="" class="http-bookmark" /></a><img src="https://s.st-hatena.com/entry.count.image?uri=https%3A%2F%2Fk0kubun.hatenablog.com%2Fentry%2Fus-investment" alt="" class="http-star" /></li> </ul> <h1><a class="keyword" href="http://d.hatena.ne.jp/keyword/OSS">OSS</a>活動</h1> <p>新作は<a href="https://github.com/k0kubun/rspec-openapi">rspec-openapi</a>で、こういう一瞬で作れるけど爆裂に便利な小さいツールは思いついたら書くのをやり続けたい。<a class="keyword" href="http://d.hatena.ne.jp/keyword/JIT">JIT</a>開発に必要だったのでdwarfを勉強して<a href="https://github.com/k0kubun/dwarftree">dwarftree</a>というのも書いていて、これはMJITの開発をする上で便利に使っている。</p> <p>とはいえいろいろ作り続けた反動で、多い時は一日3回、少なくとも週に数回は<a class="keyword" href="http://d.hatena.ne.jp/keyword/GitHub">GitHub</a>のissueかPRの通知が来るようになり、ほとんど真面目に対応しているんだけど時間の配分が結構難しくなってきた。自分がやりたくてやっている<a class="keyword" href="http://d.hatena.ne.jp/keyword/JIT">JIT</a>の開発はさておき、それと育児や学業の他に別に時間が余ってるわけでもないのに他人の要望に対応するというのは正直大変<a href="#f-9bddfb09" name="fn-9bddfb09" title="労力をかけずにマージできるPRが来ることは1%くらいしかなくて、他は1回あたり数分から数時間飛ぶ">*3</a>になってきたのだけど、<a href="https://github.com/sponsors/k0kubun">GitHub Sponsors</a>で毎年<a class="keyword" href="http://d.hatena.ne.jp/keyword/Ruby">Ruby</a> Prize最終ノミネートくらいのお金がいただけるようになったので、実はこれで結構精神的に救われている。</p> <p>メインにやっている<a class="keyword" href="http://d.hatena.ne.jp/keyword/Ruby">Ruby</a>の<a class="keyword" href="http://d.hatena.ne.jp/keyword/JIT">JIT</a>開発は、<a href="https://k0kubun.hatenablog.com/entry/2019-summary">2020年の目標</a>にもしていた<a class="keyword" href="http://d.hatena.ne.jp/keyword/Rails">Rails</a>の高速化は大きな進捗はしたものの達成できず、その分最も公式な<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%D9%A5%F3%A5%C1%A5%DE%A1%BC%A5%AF">ベンチマーク</a>であるOptcarrotの3倍高速化を<a href="https://benchmark-driver.github.io/benchmarks/optcarrot/commits.html#chart-1">期末試験が終わったあたりから本気を出す</a>ことでどうにか達成した。<a class="keyword" href="http://d.hatena.ne.jp/keyword/Ruby">Ruby</a> <a class="keyword" href="http://d.hatena.ne.jp/keyword/3x3">3x3</a>以外にも<a href="https://twitter.com/k0kubun/status/1342004509942280192">かなりいろいろ</a>やっていて、妻の多大な協力のおかげで、一人が一年で作れる範囲ではとても多くの成果を出せたと思う。</p> <h1>2021年は</h1> <p>まずコロナが収束して欲しいという切実な思いがある。長らく会えてない人に会ったり、子供にいろんなことを体験させたりしたい。あと帰国の自由度が上がるよう、<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%B0%A5%EA%A1%BC%A5%F3%A5%AB%A1%BC%A5%C9">グリーンカード</a>の申請が終わらないまでも進捗はして欲しい。</p> <p>個人目標は、2017年から言ってるけど<a class="keyword" href="http://d.hatena.ne.jp/keyword/JIT">JIT</a>で<a class="keyword" href="http://d.hatena.ne.jp/keyword/Rails">Rails</a>が速くなるようにするのと、取る授業全部成績A、といったところ。</p> <div class="footnote"> <p class="footnote"><a href="#fn-d28b918b" name="f-d28b918b" class="footnote-number">*1</a><span class="footnote-delimiter">:</span><span class="footnote-text">なのでRubyKaigiもCFP通ってたけどTakeoutには登壇しなかった</span></p> <p class="footnote"><a href="#fn-a6acefad" name="f-a6acefad" class="footnote-number">*2</a><span class="footnote-delimiter">:</span><span class="footnote-text">というか<a class="keyword" href="http://d.hatena.ne.jp/keyword/TOEIC">TOEIC</a>でもそうなんだけど、リーディングがめちゃくちゃ遅くて解ききらないことが多かった</span></p> <p class="footnote"><a href="#fn-9bddfb09" name="f-9bddfb09" class="footnote-number">*3</a><span class="footnote-delimiter">:</span><span class="footnote-text">労力をかけずにマージできるPRが来ることは1%くらいしかなくて、他は1回あたり数分から数時間飛ぶ</span></p> </div> k0kubun