Page 1
創作プラットフォームにおける
コンピュータサイエンス vs 俺たち
Computer Science vs. Us: An Engineering Story from pixiv
pixiv Inc.
USAMI Kenta
2025-10-13 #traPavilion東京科学大traP10周年カンファレンス
公開日:
by USAMI Kenta@tadsan
に東京都台東区の浅草橋ヒューリックホール&カンファレンスで開催された『traPavilion』でスポンサーセッション(10分)として発表しました。
に東京都新宿区の株式会社キュービックで開催された『第180回 PHP勉強会@東京』でレギュラーセッション(20分)として発表しました。
2025-10-13 #traPavilion東京科学大traP10周年カンファレンス
お前誰よ
お前誰よ
お前誰よ
CSっぽいカリキュラム全然なくて絶望した
お前誰よ
pixivとDBを直接共有しているのはPHP (モノレポ)
それ以外は開発時期や体制に応じていろいろ
CPUバウンドスループット重要
WebSocket
CPUバウンドスループット重要
C10K問題
WebSocket
CPUバウンドスループット重要
C10K問題
普通のWebサービスはDBのI/Oで律速するので言語は支配的ではない
こういう言語の型解析とかFWについて発信してます
現役の学生にはPHPへの感情は特にないかも
20年以上Webを支えている言語
個人的にはハックしがいのあるおもしろ言語
pixivは2007年から絶え間なく開発が続いている
いろんな人たちの問題解決が詰まっている
さも自分がやった仕事のように紹介します
/data/www/www.pixiv.net (document root)├── index.php├── novel│ └── show.php├── yyy.php└── zzz.php
/data/www/www.pixiv.net (document root)├── index.php├── novel│ └── show.php├── yyy.php└── zzz.php
/data/www/www.pixiv.net (document root)├── index.php├── novel│ └── show.php├── yyy.php└── zzz.php
/data/www/www.pixiv.net (document root)├── index.php├── novel│ └── show.php├── yyy.php└── zzz.php
/data/www/www.pixiv.net (document root)├── index.php├── novel│ └── show.php├── yyy.php└── zzz.php
/data/www/www.pixiv.net (document root)├── index.php├── novel│ └── show.php├── yyy.php└── zzz.php
/data/www/www.pixiv.net (document root)├── index.php├── novel│ └── show.php├── yyy.php└── zzz.php
/data/www/www.pixiv.net (document root)├── index.php├── novel│ └── show.php├── yyy.php└── zzz.php
/data/www/www.pixiv.net (document root)├── index.php├── novel│ └── show.php├── yyy.php└── zzz.php
/data/www/www.pixiv.net (document root)├── index.php├── novel│ └── show.php├── yyy.php└── zzz.php
ファイルをサーバにコピーすればデプロイ完了する
Railsとか使えば綺麗なURLになるよね
NovelController#show
# routes.rb get '/', to: 'index'get '/n/:id', to: 'novel#show'get '/u/:id', to: 'user#show'get '/yyy', to: 'yyy'get '/zzz', to: 'zzz'
NovelController#show
# routes.rb get '/', to: 'index'get '/n/:id', to: 'novel#show'get '/u/:id', to: 'user#show'get '/yyy', to: 'yyy'get '/zzz', to: 'zzz'
NovelController#show
# routes.rb get '/', to: 'index'get '/n/:id', to: 'novel#show'get '/u/:id', to: 'user#show'get '/yyy', to: 'yyy'get '/zzz', to: 'zzz'
NovelController#show
# routes.rb get '/', to: 'index'get '/n/:id', to: 'novel#show'get '/u/:id', to: 'user#show'get '/yyy', to: 'yyy'get '/zzz', to: 'zzz'
NovelController#show
# routes.rb get '/', to: 'index'get '/n/:id', to: 'novel#show'get '/u/:id', to: 'user#show'get '/yyy', to: 'yyy'get '/zzz', to: 'zzz'
NovelController#show
# routes.rb get '/', to: 'index'get '/n/:id', to: 'novel#show'get '/u/:id', to: 'user#show'get '/yyy', to: 'yyy'get '/zzz', to: 'zzz'
NovelController#show
# routes.rb get '/', to: 'index'get '/n/:id', to: 'novel#show'get '/u/:id', to: 'user#show'get '/yyy', to: 'yyy'get '/zzz', to: 'zzz'
pixivはフレームワークに乗ってない
pixiv本体にもURL正規化の流れ
# routes.rb get '/', to: 'index'get '/n/:id', to: 'novel#show'get '/u/:id', to: 'user#show'get '/yyy', to: 'yyy'get '/zzz', to: 'zzz'
# routes.rb get '/', to: 'index'get '/n/:id', to: 'novel#show'get '/u/:id', to: 'user#show'get '/yyy', to: 'yyy'get '/zzz', to: 'zzz'
# routes.rb get '/', to: 'index'get '/n/:id', to: 'novel#show'get '/u/:id', to: 'user#show'get '/yyy', to: 'yyy'get '/zzz', to: 'zzz'
定数URLはハッシュテーブルでO(n)で取得
# routes.rb get '/', to: 'index'get '/n/:id', to: 'novel#show'get '/u/:id', to: 'user#show'get '/yyy', to: 'yyy'get '/zzz', to: 'zzz'
定数URLはハッシュテーブルでO(n)で取得
URLにIDが組み込まれている場合は…?
定数URLはハッシュテーブルでO(n)で取得
ボトルネックじゃなけりゃ雑に処理すればいいじゃん(大富豪の発想)
pixiv本体にもURL正規化の流れ
たったの100個でこの有様これだから線形時間はだめ
URLルーティングには実装の定石がある
正規表現ベース実装
基数木(パトリシアトライ)
get '/', to: 'index'get '/xxx', to: 'xxx#index'get '/xxx/:id', to: 'xxx#shoq'get '/xxx/yyy', to: 'yyy'get '/xxx/zzz’, to: 'zzz'
get '/', to: 'index'get '/xxx', to: 'xxx#index'get '/xxx/:id', to: 'xxx#shoq'get '/xxx/yyy', to: 'yyy'get '/xxx/zzz’, to: 'zzz'
{"", : {"#result": "index"}"xxx", : {"": {"#result": "xxx#index"},":id": {"#result": "xxx#show"},"yyy": {"#result": "yyy"},"zzz": {"#result": "zzz"},...
正規表現vsパトリシアトライ
選ばれたのはパトリシアトライでした
パトリシアトライを実装しよう
ルーティングはできた
めでたしめでたし
🎉
あとは既存コードをURLルーターに載せればいいだけ
/data/www/www.pixiv.net (document root)├── index.php├── novel│ └── show.php├── yyy.php└── zzz.php
/data/www/www.pixiv.net (document root)├── index.php├── novel│ └── show.php├── yyy.php└── zzz.php
/data/www/www.pixiv.net (document root)├── index.php├── novel│ └── show.php├── yyy.php└── zzz.php
/data/www/www.pixiv.net (document root)├── index.php├── novel│ └── show.php├── yyy.php└── zzz.php
現実にはファイルが何百個もある!!!
/data/www/www.pixiv.net├── index.php├── novel│ └── show.php├── yyy.php└── zzz.php(実際にはファイルが数百個)
/data/www/www.pixiv.net├── index.php├── novel│ └── show.php├── yyy.php└── zzz.php(実際にはファイルが数百個)
/data/www/www.pixiv.net├── index.php├── novel│ └── show.php├── yyy.php└── zzz.php(実際にはファイルが数百個)
www.pixiv.net/inc/├── IndexController.php├── Novel│ └── ShowController.php├── YyyController.php└── ZzzController.php
/data/www/www.pixiv.net├── index.php├── novel│ └── show.php├── yyy.php└── zzz.php(実際にはファイルが数百個)
手で移植するのはナンセンス
今も同じコードが元気に走り続けてます
Notes on Programming in C
ルール2: 計測すべし。計測するまでは速度のための調整をしてはならない。コードの一部が残りを圧倒しないのであれば、なおさらである。
̶ Rob Pike
https://www.lysator.liu.se/c/pikestyle.html
訳語はUNIX哲学 - Wikipediaより引用(2025年10日2日12:33:03版)
裏返せば、計測してみてスループット悪化の主要因と判断されない限り安全性と開発者体験を優先
PHPには型宣言の機能がある
処理系が実行時に自動型チェックを実施
言語のホットスポットは処理系で改善されると嬉しい
現代はJITが改善され型宣言した方が最適化の恩恵を受ける
当てずっぽうで「速い」ものを選んでも問題解決にならない
これからの時代こそ自我をもって問題解決しよう
