転職と技術雑談

会社の同期が退職するということで土曜日にオンライン飲み会を開いた。転職とかキャリアとかそれっぽい話もしつつ、けっきょく技術雑談が一番盛り上がった: Denoがシングルバイナリで嬉しいという話 CPythonのオブジェクトアロケーションのコードを読んだ話 さくっと使えるML系言語としてF#がいいという話 MutatingAdmissionWebhookを試している話 Progressive Deliveryが流行っているらしい話 シェルを書いてみると勉強になる話 同期が辞めるといろいろ考えてしまうな。新卒で入った会社に一生いることは無さそうだけど、自分がいつまでいるのかはよく分からない。

2021-09-12 10:29:36 (+0900)

連結リスト実装の工夫

最近CPythonのメモリ管理のコード (obmalloc.c) を読んでいたのだが、いろいろなところで連結リストが使われていた。教科書的な連結リストの実装と比べていくつか工夫が見られて面白かったのでメモしておく: ノードを配列としてまとめて確保 ソートされた連結リストへの挿入のためのインデックス arena_objectの説明 CPythonはメモリを管理する単位は色々あるのだが、一番大きい単位がアリーナである。アリーナはデフォルトで256KiBある。ただのメモリのかたまりであるアリーナの情報を管理しているのがarena_objectという構造体で、これが連結リストのノードになっている。 arena_objectは以下の3つの状態をもつ: アリーナが割り当てられていない アリーナが割り当てられていて、空きがある アリーナが割り当てられているが、空きがない 1の状態のarena_objectはunused_arena_objectsという単連結リストにつながれていて、2の状態のarena_objectはusable_arenasという双連結リストにつながれている。 usable_arenasはnfreepoolsという値について昇順になるようにソートされていて、空きの少ないアリーナほど前に来るようになっている。その結果、リストの後方にある空きの多いアリーナが解放される可能性を高めているのである。 実装の工夫 すべてのarena_objectはarenasというグローバルな配列で確保されている。この配列の長さは最初16で、新たなarena_objectが必要になったときはreallocして配列の長さを2倍にするという実装になっている。教科書的な連結リストの実装だとノードを追加するたびにmallocするが、ここではJavaのArrayListのような仕組みになっている。 これによってノード追加時の最悪計算量がO(n)になってしまうが、そのかわり空間局所性が高くキャッシュが効きそうだ。 他の工夫としてusable_arenasへの挿入がある。ソートされた連結リストの適切な場所に新たなノードを挿入するにはO(n)の時間がかかるが、nfp2lasta[MAX_POOLS_IN_ARENA + 1]という配列をルックアップすることによってどこに挿入すればいいかO(1)で分かるようになっている。

2021-09-05 15:42:12 (+0900)

GC入門

PPLサマースクール2021「JavaScript処理系とChromeブラウザの実装技術」というイベントに参加することになった。何か予習したいと思って、プログラムを見るとGCの話がけっこうあるので少し勉強した。 GCの話って概要だけ聞いてもあまり面白そうに聞こえないんだよな。「ポインタをたどっていって生きているオブジェクトにマークする、マークのついていないやつは死んでいるから片付ける」と言われてもまあそんなもんかなという感じ。 しかし実装を追ってみるとけっこう面白い。自分はふだんPythonを書いているので、Python (cpython) のGCコードを読んでいる (obmalloc.c) 。『ガベージコレクションのアルゴリズムと実装』に解説があるしソースコードのコメントもかなり詳しいので読みやすい。 Pythonのオブジェクトはintだろうがfloatだろうがヒープに確保される。intを作るたびにmallocを呼んでいては大変なのでそういうことはしない。Pythonのアロケーター (pymalloc) は256Kiバイト領域(アリーナ)単位でメモリを確保しておいて、256バイト以下のオブジェクトについてはその中のどこかに配置される。 こうやってpymallocは基本的に自前でオブジェクトのアロケーションをして、必要なときだけmallocを呼ぶようになっている。リソースを階層化しておいて必要な時だけ下の階層を呼ぶというのは他の分野でもよくあるので面白い。 あとは空き領域の管理には連結リストが使われていたりするのだが (struct arena_object) 、これも面白かった。アプリケーションプログラミングで連結リストを使うことはめったにないがこういうときには便利なんだなーと思ったり。 けっきょくGCというよりはオブジェクトのアロケーションの話になってしまったがこんなところで。

2021-08-31 07:40:09 (+0900)

うまく仕事をサボるのは難しい

いい感じに仕事をサボれないかなーということを最近考えている。というのも自分の認知資源の大半を仕事に費やしているのことに不毛さを感じはじめたからである。数学をやるにしても本を読むにしても趣味のプログラミングをするにしても、会社でちまちまプロジェクトを進めるより有意義ではないか。 実際、半年前に育休を取っていたときはリーマン面を勉強したりコンパイラを書いたりして手応えのある生活ができていた気がする。ミルク作ったりおむつ替えたりけっこう時間がかかるんだけど、そのリソースはそこまで自分のやりたいこととコンフリクトしないのだ。 6割くらいの労力で8割くらいのアウトプット出せたら十分かなーと考えて試していたが意外と難しい。チームの中で自分が一番コード品質にうるさいので、自分が多少リファクタリングをサボっても誰にも文句言われない。ということで今までだったらやっていたリファクタリングをサボったりしてみると、機能追加のためにコードをいじるのが嫌になってかえってストレスが溜まる。やはりうまくサボるのは難しい。 そもそも仕事を頑張っている状態というのは本質的に楽なのだ。どうせ毎日8時間くらいはやらないといけないので、優先度の高い状態でやるほうがストレスは少ない。人生において仕事の優先度を下げると、優先度低いことをなんでこんなにやらないといけないんだとなって不満がたまっていく。 じゃあ楽な方を選べばいいんだが、それではつまらないと思うのでいろいろ試しているわけだ。社内にはフルタイムで仕事をしながら本を書いたりしてる人もいるわけで、彼らはどうやっているのかなあ。

2021-08-28 15:30:01 (+0900)