不定期に誰に向けるでもなく PHP に関する雑な殴り書きをしている。気がつけば 1 度も投稿することなく 1 月が終わろうとしていたくらいの雑さ加減。
phpy がまあまあ熱心に更新されている
- https://github.com/swoole/phpy
- phpy は swoole の人が作った PHP の C 拡張
- CPython の VM をそのまま埋め込み、PHP 側と Python 側で相互にコードを呼び出せるよう橋渡しをしている
- つまり同じプロセス内に PHP と Python 両方の公式 VM を同居させるということ
- wxPython で GUI アプリも書けるし
- torch だの transformers だのをインポートして今をときめく LLM を読み込む感じのコードも書ける
- パッと見だとキテレツなキワモノに見えるものの、ありのままの公式処理系 2 つを薄いブリッジで橋渡すような作りに近いので実はかなり堅い作りと思う
- queue とかプロセス間通信の仕組みで下手に PHP 側と Python 側をきっちり分離しながら作ろうとするより、ほとんどの場合にお手軽でかつちゃんと機能しやすい仕組みになるんでなかろうか
- PyDict を Python コードで読み書きするより PHP 側で読み書きする方が速いというのが笑いどころ
- phpcondo でも喋った のだけど、こっちの日記には書いたつもりでまだ書いてなかった
NativePHP の 2024 年の抱負
- https://github.com/NativePHP/laravel/discussions/248
- Tauri サポートしてかつ Web サーバ依存をなくそうとしているらしい
闇 PHP 勉強会的な何かの気配
- https://github.com/hachiojipm/ya8-2024/discussions/16
- ya8 で闇 PHP っぽい何かが行われるのではないかという気配がある
- 東京だと土日でフラっと子供連れて遊びに行けなくもないので、行きたい気もする
Psalm でプロセスあたり 5GB とか 8GB とかメモリ使うのを 2.5GB くらいで済むようにした
- https://github.com/vimeo/psalm/issues/10522#issuecomment-1881729504
- Reli のメモリ解析機能を使ったメモリ問題辻斬り妖怪プレイの 3 つ目
- PHP で特定のキーのセットで複数の値を持つようなものを作る場合、ほぼ常に配列よりオブジェクトの方がメモリ効率が良い
- 連想配列では最低 8 要素分の bucket 領域(1 つ 32 byte なので 256 byte)とハッシュテーブル用領域(要素数の倍の数の 4byte int 領域なので 64 byte)がアロケーションされ、埋まると 2 倍ずつ領域が伸長されるので領域を余分に確保しがちで、またヘッダ的な領域でも 56 byte を食うため、計 376 byte が必要。要素数が増える際のサイズ増加も激しい。
- オブジェクトではヘッダ的な領域が 40 バイトあり、その後続領域へ zval の配列が宣言済みプロパティの数だけ続くので、プロパティがなければその 40 バイトだけ、1 つあっても 16 byte 足して 56 byte のみ。
- 連想配列では各インスタンスがキーと値を紐付けるハッシュテーブルを持つ必要があるのに対し、オブジェクトの場合はクラス情報側へプロパティ名とインスタンス領域のオフセットを紐付けるハッシュテーブルを 1 つ持つだけで済むので、このような効率差が出る
- 一方、オブジェクトでも動的プロパティを使おうとするとインスタンスごとに宣言済みプロパティすべてを含むハッシュテーブルが必要になってしまうため、実質的にオブジェクトの領域 + 配列領域のサイズになってメモリ効率が最悪になる
- この動的プロパティテーブルは
\unserialize()
で生成されたオブジェクトには動的プロパティを実際には使ってなくとも必ず付いてきてしまうので、並列処理プロセスとの IPC やキャッシュにシリアライズを使う Psalm でめちゃくちゃ大きな差になっていた - わりと笑えることに、
__unserialize()
を実装したクラスではこの動的プロパティテーブルの生成が処理系内でバイパスされるので、必要なあたりに__unserialize()
を付けてまわってデフォルトシリアライズ方式でのメモリ消費量を軽くした - 本当は igbinary だと interning でデフォルトシリアライズ方式よりメモリ消費を削れる部分もあるのだけど、この動的プロパティテーブルの生成回避ができないのがネック