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

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

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

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

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

    View full-size slide

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

    View full-size slide

  3. Laravel.shibuya
    Ryo Tomidokoro / @hanhan1978

    View full-size slide

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

    View full-size slide

  5. Laravel.shibuya
    Ryo Tomidokoro / @hanhan1978

    View full-size slide

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

    View full-size slide

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

    View full-size slide

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

    View full-size slide

  9. Laravel.shibuya
    Ryo Tomidokoro / @hanhan1978

    View full-size slide

  10. データ量
    posts 10000

    users 1000

    post_posts 33864
    Laravel.shibuya
    Ryo Tomidokoro / @hanhan1978

    View full-size slide

  11. 以後の高速化の指標
    siege -t 10s -c 50 -b localhost
    Transaction Rate (Req/Sec)
    の3回平均
    初期状態は 195.84
    Laravel.shibuya
    Ryo Tomidokoro / @hanhan1978

    View full-size slide

  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

    View full-size slide

  13. 2. opcache.jit
    無効化
    zend_extension=opcache.so

    ;opcache.jit=disable

    効果なし (CPU
    バウンドじゃない)
    199.29 (Req/Sec)
    Laravel.shibuya
    Ryo Tomidokoro / @hanhan1978

    View full-size slide

  14. 3. opcache
    無効化
    ;zend_extension=opcache.so

    抜群の効果
    125.00 (Req/Sec)
    Laravel.shibuya
    Ryo Tomidokoro / @hanhan1978

    View full-size slide

  15. 4. xdebug
    有効化
    zend_extension=xdebug

    地味な一撃
    101.90 (Req/Sec)
    Laravel.shibuya
    Ryo Tomidokoro / @hanhan1978

    View full-size slide

  16. ここまでの総評
    気づかれずにミドルで与える打撃はこのくらい。

    もっと過激な手段としては
    prefork
    の startServer 1
    PHP
    のバージョンダウン
    Laravel.shibuya
    Ryo Tomidokoro / @hanhan1978

    View full-size slide

  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

    View full-size slide

  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

    View full-size slide

  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

    View full-size slide

  20. 総評
    現場でありえそうなコードでも、50msec -> 1.5 sec
    程度に低速化
    単体アクセスも遅いが、特に並列化性能は 30
    倍程度劣化
    ※複雑化したコードベースでは注意しないとすぐ劣化
    Laravel.shibuya
    Ryo Tomidokoro / @hanhan1978

    View full-size slide

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

    View full-size slide

  22. 1. apcu
    キャッシュ
    apcu_store('key', $posts);

    メモリキャッシュ最高
    865.7 (Req/Sec)
    Laravel.shibuya
    Ryo Tomidokoro / @hanhan1978

    View full-size slide

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

    OPCache
    に乗る
    1098 (Req/Sec)
    Laravel.shibuya
    Ryo Tomidokoro / @hanhan1978

    View full-size slide

  24. 3. var_export
    して preload
    上の /tmp/posts.php
    を preload
    してしまう
    1300 (Req/Sec)
    Laravel
    で 5msec
    の世界
    Laravel.shibuya
    Ryo Tomidokoro / @hanhan1978

    View full-size slide

  25. これなら Isucon
    勝てる?
    単純比較は出来ないが、多分無理。
    静的 HTML
    すると 8000 (Req/Sec)
    Nginx
    でやってみると 12000 (Req/Sec)
    Go
    は、この1.5
    倍くらいなので、18000
    と仮定すると、あと13
    倍速
    くすればワンチャンある。
    Laravel.shibuya
    Ryo Tomidokoro / @hanhan1978

    View full-size slide

  26. Octane
    は?
    ソース見てないので実測だけだが、単純な高速化において swoole
    ベースで 、今回の 6
    割くらいの性能に収まった。
    レースコンディションで問題を起こさないようにするために、どこ
    かで同期処理が入っているのだと思う。
    Laravel.shibuya
    Ryo Tomidokoro / @hanhan1978

    View full-size slide

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

    View full-size slide