Upgrade to Pro — share decks privately, control downloads, hide ads and more …

俺の Laravel がこんなに速いわけがない! / My Laravel Too Fast

俺の Laravel がこんなに速いわけがない! / My Laravel Too Fast

Laravel を意図的に低速化していくことで、どのようなコードがどれくらいの影響を速度面で与えるかを勉強します。

F04982ad61107b5408ad139966596316?s=128

Ryo Tomidokoro

June 29, 2022
Tweet

More Decks by Ryo Tomidokoro

Other Decks in Technology

Transcript

  1. 俺の Laravel がこんなに速い わけない! 2022-06-22 Laravel.shibuya Ryo Tomidokoro / @hanhan1978

  2. はじめに Laravel は遅くて有名? Laravel.shibuya Ryo Tomidokoro / @hanhan1978

  3. Laravel.shibuya Ryo Tomidokoro / @hanhan1978

  4. しかし、実際に簡易ブログを作ってみると... ※ 10000 レコードの中規模想定 Laravel.shibuya Ryo Tomidokoro / @hanhan1978

  5. Laravel.shibuya Ryo Tomidokoro / @hanhan1978

  6. 充分速い! これじゃ、評判と違う Laravel.shibuya Ryo Tomidokoro / @hanhan1978

  7. 低速化 Laravel の実装や実行環境を工夫して、 評判通りに遅くしよう! ※なるべく気づかれないように遅くする技術 Laravel.shibuya Ryo Tomidokoro / @hanhan1978

  8. アプリの仕様 シンプルなブログアプリ Laravel.shibuya Ryo Tomidokoro / @hanhan1978

  9. Laravel.shibuya Ryo Tomidokoro / @hanhan1978

  10. データ量 posts 10000 users 1000 post_posts 33864 Laravel.shibuya Ryo Tomidokoro

    / @hanhan1978
  11. 以後の高速化の指標 siege -t 10s -c 50 -b localhost Transaction Rate

    (Req/Sec) の3回平均 初期状態は 195.84 Laravel.shibuya Ryo Tomidokoro / @hanhan1978
  12. 1. preload 無効化 zend_extension=opcache.so ;opcache.preload=/var/www/src/preload.php ;opcache.preload_user=www-data 効果なし (CPU バウンドじゃない) 195.39

    (Req/Sec) Laravel.shibuya Ryo Tomidokoro / @hanhan1978
  13. 2. opcache.jit 無効化 zend_extension=opcache.so ;opcache.jit=disable 効果なし (CPU バウンドじゃない) 199.29 (Req/Sec)

    Laravel.shibuya Ryo Tomidokoro / @hanhan1978
  14. 3. opcache 無効化 ;zend_extension=opcache.so 抜群の効果 125.00 (Req/Sec) Laravel.shibuya Ryo Tomidokoro

    / @hanhan1978
  15. 4. xdebug 有効化 zend_extension=xdebug 地味な一撃 101.90 (Req/Sec) Laravel.shibuya Ryo Tomidokoro

    / @hanhan1978
  16. ここまでの総評 気づかれずにミドルで与える打撃はこのくらい。 もっと過激な手段としては prefork の startServer 1 PHP のバージョンダウン Laravel.shibuya

    Ryo Tomidokoro / @hanhan1978
  17. 5. eager loading 廃止 $posts = \App\Models\Post::take(20); //->with('user') //->with('linkPosts') //->with('linkedPosts')->get();

    効果は抜群だ! 22.76 (Req/Sec) Laravel.shibuya Ryo Tomidokoro / @hanhan1978
  18. 6. limit 句 廃止 $posts = \App\Models\Post::get(); return view(...)->with('posts', $posts->take(20));

    mysqlnd の優秀さがわかる 12.83 (Req/Sec) Laravel.shibuya Ryo Tomidokoro / @hanhan1978
  19. 7. Attribute Casting 乱用 foreach($posts as $post){ $post->created_at; $post->updated_at; $post->created_at;

    $post->updated_at; } Carbon の生成コストを侮るなかれ 6.5 (Req/Sec) Laravel.shibuya Ryo Tomidokoro / @hanhan1978
  20. 総評 現場でありえそうなコードでも、50msec -> 1.5 sec 程度に低速化 単体アクセスも遅いが、特に並列化性能は 30 倍程度劣化 ※複雑化したコードベースでは注意しないとすぐ劣化

    Laravel.shibuya Ryo Tomidokoro / @hanhan1978
  21. おまけ カリカリチューニング編 Laravel.shibuya Ryo Tomidokoro / @hanhan1978

  22. 1. apcu キャッシュ apcu_store('key', $posts); メモリキャッシュ最高 865.7 (Req/Sec) Laravel.shibuya Ryo

    Tomidokoro / @hanhan1978
  23. 2. var_export して include $posts は stdclass で中身を置き換えた上で file_put_contents('/tmp/posts.php', '<?php

    $posts='.var_export($posts, true)); include('/tmp/posts.php'); OPCache に乗る 1098 (Req/Sec) Laravel.shibuya Ryo Tomidokoro / @hanhan1978
  24. 3. var_export して preload 上の /tmp/posts.php を preload してしまう 1300

    (Req/Sec) Laravel で 5msec の世界 Laravel.shibuya Ryo Tomidokoro / @hanhan1978
  25. これなら Isucon 勝てる? 単純比較は出来ないが、多分無理。 静的 HTML すると 8000 (Req/Sec) Nginx

    でやってみると 12000 (Req/Sec) Go は、この1.5 倍くらいなので、18000 と仮定すると、あと13 倍速 くすればワンチャンある。 Laravel.shibuya Ryo Tomidokoro / @hanhan1978
  26. Octane は? ソース見てないので実測だけだが、単純な高速化において swoole ベースで 、今回の 6 割くらいの性能に収まった。 レースコンディションで問題を起こさないようにするために、どこ かで同期処理が入っているのだと思う。

    Laravel.shibuya Ryo Tomidokoro / @hanhan1978
  27. じゃあどうしたら? Go を書け Open Swoole と 軽量フレームワークを組み合わせて同期処理を廃 すれば、チャンスはある。 Laravel.shibuya Ryo

    Tomidokoro / @hanhan1978