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分)として発表しました。
創作プラットフォームにおける
コンピュータサイエンス vs 俺たち
Computer Science vs. Us: An Engineering Story from pixiv
pixiv Inc.
USAMI Kenta
2025-10-13 #traPavilion
東京科学大traP10周年カンファレンス
お前誰よ
お前誰よ
お前誰よ
CSっぽいカリキュラム
お前誰よ
全然なくて絶望した
普段やってる仕事
<?php
pixivとDBを直接 共有しているのは PHP (モノレポ)
それ以外は
開発時期や体制に
応じていろいろ
CPUバウンド
スループット重要
CPUバウンド
WebSocket
スループット重要
C10K問題
CPUバウンド
WebSocket
スループット重要
C10K問題
普通のWebサービスは
DBのI/Oで律速するので
言語は支配的ではない
PHP: Hypertext Preprocessor
こういう言語の
型解析とかFWについて
PHP: Hypertext Preprocessor
発信してます
PHPは見る人の心を映す
現役の学生には PHPへの感情は
特にないかも
20年以上Webを
支えている言語
個人的には
ハックしがいのある
おもしろ言語
pixivは2007年から
絶え間なく
開発が続いている
いろんな人たちの
問題解決が
詰まっている
さも自分がやった
仕事のように紹介します
URL
ルーティング
vs 俺たち
/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'
定数URLは
get '/zzz', to: 'zzz'
ハッシュテーブルで
O(n)で取得
# routes.rb
get '/', to: 'index'
get '/n/:id', to: 'novel#show' get '/u/:id', to: 'user#show'
get '/yyy', to: 'yyy'
定数URLは
get '/zzz', to: 'zzz'
ハッシュテーブルで
O(n)で取得
# routes.rb
URLにIDが
get '/', to: 'index'
組み込まれている場合は…?
get '/n/:id', to: 'novel#show' get '/u/:id', to: 'user#show'
get '/yyy', to: 'yyy'
定数URLは
get '/zzz', to: 'zzz'
ハッシュテーブルで
O(n)で取得
ボトルネックじゃなけりゃ 雑に処理すればいいじゃん
(大富豪の発想)
URLルーター作った!
(ここまでは自分の仕事)
pixiv本体にも
URL正規化の流れ
たったの100個でこの有様 これだから線形時間はだめ
どうにかしよう
(と競プロ得意な同僚が言った)
URLルーティングには
実装の定石がある
正規表現ベース実装
基数木(パトリシアトライ)
基数木(パトリシアトライ)
基数木(パトリシアトライ)
{
get '/', to: 'index'
, : { #result : index }
"" " " " "
get '/xxx', to: 'xxx#index'
xxx , : {
" "
get '/xxx/:id', to: 'xxx#shoq'
: { #result : xxx#index },
"" " " " "
get '/xxx/yyy', to: 'yyy'
:id : { #result : xxx#show },
" " " " " "
get '/xxx/zzz’, to: 'zzz'
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
(実際にはファイルが数百個)
/data/www/www.pixiv.net www.pixiv.net/inc/
├── index.php ├── IndexController.php
├── novel ├── Novel
│ └── show.php │ └── ShowController.php
├── yyy.php ├── YyyController.php └── zzz.php └── ZzzController.php
(実際にはファイルが数百個)
手で移植するのは
ナンセンス
PHPカンファレンス2017
今も同じコードが
元気に走り続けてます
🏃
枯れた機能なので
積極的に弄る動機がない (PHPのBC breakを踏まない限り)
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が改善され
型宣言した方が
最適化の恩恵を受ける
当てずっぽうで
「速い」ものを選んでも
問題解決にならない
これからの時代こそ
自我をもって
問題解決しよう