9月11日

今日は部署の勉強会でPEP 703の解説をした。前回は入門的な話をしたので、今回は参照カウントの実装について詳しく話した。BRC論文が読みやすかったのでわりとスムーズに話せた。発表後は同僚と社食でお茶を飲みながら雑談。 あとは『訂正可能性の哲学』を手に入れた。電子書籍にするかどうか迷ったが表紙の手触りが良かったので書店で買った。 第一章は国家と家族の話。プラトン的な理想的な国家において家族のような閉鎖的なつながりは解体される。一方でポパーの批判によれば個人を全体に奉仕させようとする全体主義国家はこそが部族的で閉鎖的である。お互いが相手は閉鎖的だと非難し合うという奇妙なねじれがある。このねじれを読み解くための補助線としてトッドの仕事が引用される。 家族構造と政治制度をダイレクトに結び付けるトッドの説は単純化しすぎのように感じられたが、それらの相互作用については『「経済成長」の起源』の第5章にも書いてあったのあとで読み返す。

2023-09-11 20:00:51 (+0900)

理解のための具体例

数学を勉強するとき、具体例の果たす役割は非常に大きい。たとえばコンパクト性という概念を理解するときに、閉区間 [a, b] がその例になっていることを納得するというステップは欠かせない。あるいは「R^nの有界閉集合はコンパクトである」という事実を理解するために、反例として無限次元空間の単位閉球がコンパクトでないことを理解することも重要である。 一方で情報系では具体例に対する意識が数学ほど発達していないように思う。かわりに例え話を使って概念を説明することがよくある:「C言語の変数は箱のようなものだが、SMLの変数は箱というよりラベルである」など。 数学より情報科学の方が具体的だというのが一般的な感覚だと思うが、それも一理ある。情報科学の方が産業的な応用が多いため応用事例は数学より多く流通している。応用を知ることはモチベーションになるのでもちろん意味はあるのだが、理解のための具体例としてはサイズが大きすぎてあまり効率的ではない。 先日Lispyという100行程度のLISP実装を読んだのだが、これは理解のための具体例として非常にいい。短いので頭の中に入るサイズである。call-by-value, lexical scope, closureなどの概念はこの実装をもとによく理解できると思う。

2021-09-26 10:05:21 (+0900)

転職と技術雑談

会社の同期が退職するということで土曜日にオンライン飲み会を開いた。転職とかキャリアとかそれっぽい話もしつつ、けっきょく技術雑談が一番盛り上がった: 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)