Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
Cygamesを支えるPHPと、その高速化の取り組み
Search
Cygames
November 08, 2016
Technology
48
34k
Cygamesを支えるPHPと、その高速化の取り組み
2016/11/03 PHPカンファレンス 2016
Cygames
November 08, 2016
Tweet
Share
More Decks by Cygames
See All by Cygames
『GRANBLUE FANTASY Relink』キャラクターの魅力を支えるリグ・シミュレーション制作事例
cygames
0
270
『GRANBLUE FANTASY: Relink』最高の「没入感」を実現するカットシーン制作手法とそれを支える技術
cygames
1
230
『GRANBLUE FANTASY Relink』ソフトウェアラスタライザによる実践的なオクルージョンカリング
cygames
0
260
高品質なフォトグラメトリデータを取得するためのハードウェア&ソフトウェア開発
cygames
0
550
AIを活用した柔軟かつ効率的な社内リソース検索への取り組み
cygames
0
340
『GRANBLUE FANTASY: Relink』開発からリリースまでを支えたCI/CDの取り組み
cygames
0
150
『GRANBLUE FANTASY: Relink』専任エンジニアチームで回す大規模開発QAサイクル
cygames
0
180
『GRANBLUE FANTASY: Relink』クオリティと物量の両立に挑戦したフェイシャルアニメーション事例 ~カットシーンからランタイムまで~
cygames
0
170
『GRANBLUE FANTASY: Relink』キャラクターの個性にlinkした効果音表現
cygames
0
89
Other Decks in Technology
See All in Technology
[JAWS-UG GameTech] 第6回 各種事例紹介_18TRIPにおけるAWSサービスを活用した負荷テスト・障害テスト
naoto_yasuda
0
130
Semantic Kernel の Agent 機能試してみた!
okazuki
1
120
Oracle Database 23ai 新機能#4 Rolling Maintenance
oracle4engineer
PRO
0
120
リスクから学ぶKubernetesコンテナセキュリティ/k8s-risk-and-security
mochizuki875
1
310
XPを始める新人に伝えたい近道の鍵
nakasho
1
290
Efficient zero-copy networking using io_uring
ennael
PRO
0
320
Pythonを活用したLLMによる構造的データ生成の手法と実践
brainpadpr
3
270
LINEヤフー新卒採用 コーディングテスト解説 実装問題編
lycorp_recruit_jp
1
12k
kube-vipとkube-proxy置き換えCiliumを積んだ究極のK3sクラスタを建てる
logica0419
4
200
【shownet.conf_】ShowNet伝送改めShowNet APN 2024
shownet
PRO
0
400
【shownet.conf_】持続可能な次世代Wi-Fi運用に向けて
shownet
PRO
0
320
いまからでも遅くない! コンテナでWebアプリケーションを 動かしてみよう(2-1)WebAPI座学
nomu
0
150
Featured
See All Featured
[RailsConf 2023] Rails as a piece of cake
palkan
49
4.7k
CSS Pre-Processors: Stylus, Less & Sass
bermonpainter
355
29k
Music & Morning Musume
bryan
46
6.1k
Mobile First: as difficult as doing things right
swwweet
222
8.8k
No one is an island. Learnings from fostering a developers community.
thoeni
19
2.9k
How GitHub (no longer) Works
holman
311
140k
Learning to Love Humans: Emotional Interface Design
aarron
271
40k
Dealing with People You Can't Stand - Big Design 2015
cassininazir
364
22k
Cheating the UX When There Is Nothing More to Optimize - PixelPioneers
stephaniewalter
279
13k
Raft: Consensus for Rubyists
vanstee
136
6.6k
From Idea to $5000 a Month in 5 Months
shpigford
380
46k
Docker and Python
trallard
40
3k
Transcript
None
© Cygames, Inc. 今回お話したいこと Cygamesのアプリはピーク時には秒間5万アク セス100万クエリを捌く必要があります サーバーサイドは、最⾼高のコンテンツを開発し、 それを⾼高速かつ安定的に提供することを⽬目指して います。 今回はそのサーバー構成/技術や、どのような価
値観で開発しているかと、⾼高速化の取り組みを紹 介します!
© Cygames, Inc. 今回お話したいこと • 前半 • Cygamesのサーバー構成/技術スタック • コンテンツ開発に対してのマインドセット
• 負荷分散/⾼高速化/リリースでの取り組み • 後半 • ⾼高速化のためZephir導⼊入検討 • Zephirの概要と導⼊入 • 運⽤用してみてとこれから
© Cygames, Inc. ⾃自⼰己紹介 • ⼩小笠笠原空宙(たかひろ) • サーバーサイドエンジニーア • ほぼPHP
• ちょっとperl • 2014年年7⽉月 Cygames join • その前はモバイルサイト/ソーシャルゲーム開発
© Cygames, Inc. © Cygames, Inc. 5 ちょっと紹介
© Cygames, Inc.
© Cygames, Inc.
© Cygames, Inc.
© Cygames, Inc. © Cygames, Inc.
© Cygames, Inc. © Cygames, Inc. MySQLに変わるDB 「 CySQL 」を開発中!
•シャドーバースポータルで ⼀一部稼働済み
© Cygames, Inc.
© Cygames, Inc. 5000万DL 300万⼈人プレイ/daily
© Cygames, Inc. とあるアプリの現状 • ⽉月間300億PV • ピーク時、秒間5万アクセス • ピーク時、秒間100万クエリ
• 1⽇日のDBのトランザクションデータ増加量量 • 1〜~2TB • 1⽇日のログデータ増加量量 • 60GB〜~
© Cygames, Inc. Cygamesを⽀支えるサーバーサイド • サーバー構成/技術スタック • 何を、どのように利利⽤用しているのか • 開発スタイル/マインドセット
• どのような価値観で開発しているか • 負荷分散/⾼高速化/リリースでの取り組み • 開発~∼運⽤用までの取り組み • 今/これからの取り組み • 今後どう前進しようとしているか
© Cygames, Inc. © Cygames, Inc. 15 とあるサーバー構成例例
© Cygames, Inc. とあるサーバー構成例例(⼤大雑把な) Batch PHP Node.js PHP-‐‑‒FPM Nginx MySQL
Memcached redis
© Cygames, Inc. とあるサーバー構成例例(⼤大雑把な) Batch PHP Node.js PHP-‐‑‒FPM Nginx MySQL
Memcached redis
© Cygames, Inc. とあるサーバー構成例例(⼤大雑把な) Batch PHP Node.js PHP-‐‑‒FPM Nginx MySQL
Memcached redis
© Cygames, Inc. とあるサーバー構成例例(⼤大雑把な) Batch PHP Node.js PHP-‐‑‒FPM Nginx MySQL
Memcached redis
© Cygames, Inc. とあるサーバー構成例例(⼤大雑把な) Batch PHP Node.js PHP-‐‑‒FPM Nginx MySQL
Memcached redis
© Cygames, Inc. とあるサーバー構成例例(⼤大雑把な) Batch PHP Node.js PHP-‐‑‒FPM Nginx MySQL
Memcached redis
© Cygames, Inc. とあるサーバー構成例例(⼤大雑把な) Batch PHP Node.js PHP-‐‑‒FPM Nginx MySQL
Memcached redis
© Cygames, Inc. とあるアプリの周辺技術
© Cygames, Inc. とあるアプリの周辺技術 Ansible Vagrant Munin Mackerel Jenkins New
Relic Google BigQuery Fluentd Elasticsearch Kibana
© Cygames, Inc. © Cygames, Inc. 25 開発スタイル マインドセット
© Cygames, Inc. © Cygames, Inc. 26 ⾯面⽩白くなければ 意味がない
© Cygames, Inc. ⾯面⽩白くなければ意味がない • ⾯面⽩白さにゴールはない…
© Cygames, Inc. ⾯面⽩白くなければ意味がない • ⾯面⽩白さにゴールはない… • 素早くトライ&エラーを繰り返す • 素早く微調整を繰り返す
• それが⾏行行いやすい実装 • ⾯面⽩白くなければばっさり捨てることも厭わない
© Cygames, Inc. © Cygames, Inc. 29 CS最優先
© Cygames, Inc. CS(カスタマーサポート)最優先 • お客様からの問い合わせには即対応 • 即対応できるようなログの設計 • ログの可視化ツールの構築
• 本番環境のデータを複製し、実機で動きを確認 できる検証環境 • 確証を持って対応できるように
© Cygames, Inc. © Cygames, Inc. 31 当たり前のことを 当たり前にやる
© Cygames, Inc. 当たり前のことを当たり前にやる • ⼩小さな差がピーク時に⼤大きな差に • 不不必要な処理理は書かない • 不不必要なデータは取得しない
• 適切切なリファクタリング • 運⽤用し易易い実装、拡張しやすい実装 • ⽇日々の積み重ねが、 良良くも悪くもピーク時に顕在化する
© Cygames, Inc. 当たり前のことを当たり前にやる • 当たり前のレベルがスピードにつながる • ほぼ毎⽇日複数回デプロイ • ほぼ常にイベント開催
• 新機能追加、機能改善、etc • PJに関わる⼈人間も多くなる • 当たり前のことを増やし、積み上げることで チームのレベルを上げていく
© Cygames, Inc. © Cygames, Inc. 34 負荷分散/⾼高速化/ リリース での取り組み
© Cygames, Inc. 秒間5万アクセス 秒間5万アクセスのアクセスを 捌くため負荷分散/処理理の⾼高速化は サーバーサイドの最重要課題!
© Cygames, Inc. 負荷分散/スケールアウトの取り組み • DBは⽔水平、垂直分割 • キャッシュはTwemproxyで分散 • Node.jsはNginxでバランシング
• 各種ログは⾮非同期で保存 • バッチ処理理できるものはバッチ処理理へ • 分散/スケールアウトできるように • できるだけキャッシュ • 同期処理理は必要最低限に
© Cygames, Inc. © Cygames, Inc. 37 ⾼高速化の取り組み
© Cygames, Inc. プロファイリングの取り組み • 「推測するな、計測せよ」 • New relicで解析 •
以前はxhprofなど • 重いクエリ、最適化できる処理理などを地道に対応 • FW側の不不要な処理理なども最適化 • 4.5秒以上かかったリクエストを⽇日次で集計、通知 • 検知 ⇔ 最適化の地道な対応 イベント開始><; 負荷対策リリース\(^o^)/ レスポンスタイム推移
© Cygames, Inc. DB関連での取り組み • ボトルネックの多くはDB関連 • トランザクション中の処理理は最⼩小限に • まとめられるクエリはまとめる
• indexはカーディナリティが⾼高い順に • ⽇日次で開発環境で実⾏行行された全クエリをexplain • 問題のありそうなクエリは通知
© Cygames, Inc. DB関連での取り組み • 本番DBのGeneral_̲Log,Slow_̲Queryも解析
© Cygames, Inc. DB関連での取り組み • 本番DBのGeneral_̲Log,Slow_̲Queryも解析 • テーブル単位でサマリー • ロック、処理理件数など確認できる
© Cygames, Inc. DB関連での取り組み • 本番DBのGeneral_̲Log,Slow_̲Queryも解析 • 実際に実⾏行行されたクエリを⼀一覧 • 渡されたパラメータ等確認
• 運⽤用の過程でレコードの偏りなどで不不適切切なindex が選択されることも
© Cygames, Inc. DB関連での取り組み • 本番DBのGeneral_̲Log,Slow_̲Queryも解析 • 対象クエリのexplain表⽰示 • index,type,partition
など確認
© Cygames, Inc. DB関連での取り組み • とにかくデータがもりもり増えていく • トランザクションデータは毎⽇日1~∼2TB単位で増加 • CS/分析⽤用途の⾏行行動ログも毎⽇日60GB〜~で増加
• 必要なくなったデータは順次パージしないと ディスク容量量を圧迫してしまう
© Cygames, Inc. DB関連での取り組み • 必要なくなったデータは順次パージ • イベント単位でテーブル作成、終了了後にdrop • パーティション単位で毎⽇日drop&add
• 不不要なテーブルは週次でアラートを通知 • 常に必要なデータのみを保持するように
© Cygames, Inc. DB関連での取り組み • 数⼗十GBのテーブルを安全にdropする • データファイルが⼤大きいとファイル削除時、 io_̲waitで数秒間ではあるがレスポンス劣劣化 i.
drop対象のデータファイルにhard link貼る ii. drop table実⾏行行 iii. hard linkしたファイルのサイズを切切り詰めた後 に、remove(linuxのtruncateコマンド) • ゆるやかに削除することで数百テーブル、合計数百 GBのテーブル削除もレスポンス劣劣化なく実⾏行行
© Cygames, Inc. リリース時の取り組み • リリース前には職種/チーム問わずレビュー • 全スタッフ ≒ ゲームユーザ
• プランナー/エンジニア/デザイナ/バックオフィス • ⾯面⽩白いと確信が持てるまでブラッシュアップ • リリース前には実際に運⽤用テスト • 各種更更新作業などの通常運⽤用リハーサル • 緊急デプロイなどの障害対応フローなども確認
© Cygames, Inc. © Cygames, Inc. 48 今/これからの取り組み
© Cygames, Inc. 今/これからの取り組み • PHP7対応 • FWのcoreを拡張させている箇所の対応 • 各種extensionの対応状況の調査
• 品質と⽣生産性の向上、仕組みづくり • ゲーム特有の問題を検知できる仕組み • ユニット/E2Eテストだけではない何か • Zephirによる⾼高速化/共通化 • この後詳しく・・・
© Cygames, Inc. ⼀一旦まとめ • Cygamesサーバーサイドは、最⾼高のコンテン ツを開発し、それを⾼高速/安定的な提供を⽬目標 としています • ⽇日々、トライ&エラー/実装⇔計測を地道に繰
り返し実績を積み上げ、上記の実現を⽬目指して います!
© Cygames, Inc. © Cygames, Inc. Zephirやってみた ⼩小笠笠原 空宙
© Cygames, Inc. 経緯 • レスポンスの⾼高速化は最優先事項の1つ • クエリ/処理理最適化もある程度度やった感 • (まだまだ最適化できることはあるけど…)
• 違う⾓角度度からの最適化を⾏行行いたい
© Cygames, Inc. Zephir検討への経緯 • レスポンスの⾼高速化は最優先事項の1つ • クエリ/処理理最適化もある程度度やった感 • (まだまだ最適化できることはあるけど…)
• 違う⾓角度度からの最適化を⾏行行いたい ミドルウェアのバージョン 上げようぜ!
© Cygames, Inc. Zephir検討への経緯 • レスポンスの⾼高速化は最優先事項の1つ • クエリ/処理理最適化もある程度度やった感 • (まだまだ最適化できることはあるけど…)
• 違う⾓角度度からの最適化を⾏行行いたい ミドルウェアのバージョン 上げようぜ! フレームワーク変えようぜ!
© Cygames, Inc. Zephir検討への経緯 • レスポンスの⾼高速化は最優先事項の1つ • クエリ/処理理最適化もある程度度やった感 • (まだまだ最適化できることはあるけど…)
• 違う⾓角度度からの最適化を⾏行行いたい ミドルウェアのバージョン 上げようぜ! フレームワーク変えようぜ! ⾔言語変えようぜ!
© Cygames, Inc. Zephir検討への経緯 • レスポンスの⾼高速化は最優先事項の1つ • クエリ/処理理最適化もある程度度やった感 • (まだまだ最適化できることはあるけど…)
• 違う⾓角度度からの最適化を⾏行行いたい ミドルウェアのバージョン 上げようぜ! フレームワーク変えようぜ! ⾔言語変えようぜ! ⾯面⽩白くなければ意味がない エンジニア的にはやってみたいんだがしかし・・・
© Cygames, Inc. Zephir検討への経緯 • レスポンスの⾼高速化は最優先事項の1つ • クエリ/処理理最適化もある程度度やった感 • (まだまだ最適化できることはあるけど…)
• 違う⾓角度度からの最適化を⾏行行いたい ミドルウェアのバージョン 上げようぜ! フレームワーク変えようぜ! ⾔言語変えようぜ! ⾯面⽩白くなければ意味がない エンジニア的にはやってみたいんだがしかし・・・ Zephirっていうのが あるらしいぞい
© Cygames, Inc. Zephirとは • PHPerでも簡単にextensionが書ける⾔言語 • PHPのような記述でextensionが作成できる • if⽂文の書式が違う
• 変数に$使わない • 変数上書き時は、let を使う • 静的/動的型⾔言語 • メモリ管理理等が必要ない • ⾼高速FW PhalconはZephirで実装
© Cygames, Inc. Zephirについて • Hello World namespace Utils; class
Hello { //say func public static function say() { echo "Hello World!"; } } <?php Utils¥Hello::say(); // prints Hello World! $zephir build
© Cygames, Inc. Extensionが⽣生成/実⾏行行までのフロー 1. Zephirのスケルトンを作成 $zephir init utils utils
├── ext //Zephirのcore,⽣生成されるextensionなどが配置される │ └── utils //ここに.zepファイルを作成していく
© Cygames, Inc. Extensionが⽣生成/実⾏行行までのフロー 2.Zephirのファイルを作成 $vim utils/hello.zep namespace Utils; class
Hello { public static function say() { echo "Hello World!"; } }
© Cygames, Inc. Extensionが⽣生成/実⾏行行までのフロー 3.Zephirでextension⽣生成→compile • ZephirがPHPで.zepファイルを解析 • C⾔言語のextensionファイル群⽣生成 •
gccでコンパイル、.soファイルをext_̲dirにコピー $zephir build Compiling... Installing... Extension installed! Don't forget to restart your web server hello.zep C⾔言語 utils ext ファイル群 utils.so PHP gcc
© Cygames, Inc. どんなソースが⽣生成される? • Zephirでフィボナッチ数列列 • 定義通り再帰でやってみる class Fib
{ public function calc(int n) -‐‑‒> int { if n < 2 { return n; } return self::calc(n -‐‑‒ 1) + self::calc(n -‐‑‒ 2); } }
© Cygames, Inc. どんなソースが⽣生成される? PHP_̲METHOD(Utils_̲Fib, calc) { zval *n_̲param =
NULL, *_̲0 = NULL, *_̲1 = NULL, *_̲2 = NULL; int n, ZEPHIR_̲LAST_̲CALL_̲STATUS; ZEPHIR_̲MM_̲GROW(); zephir_̲fetch_̲params(1, 1, 0, &n_̲param); n = zephir_̲get_̲intval(n_̲param); if (n < 2) { RETURN_̲MM_̲LONG(n);} ZEPHIR_̲INIT_̲VAR(_̲1); ZVAL_̲LONG(_̲1, (n -‐‑‒ 1)); ZEPHIR_̲CALL_̲SELF(&_̲0, "calc", NULL, 0, _̲1); zephir_̲check_̲call_̲status(); ZEPHIR_̲INIT_̲NVAR(_̲1); ZVAL_̲LONG(_̲1, (n -‐‑‒ 2)); ZEPHIR_̲CALL_̲SELF(&_̲2, "calc", NULL, 0, _̲1); zephir_̲check_̲call_̲status(); zephir_̲add_̲function(return_̲value, _̲0, _̲2); RETURN_̲MM(); }
© Cygames, Inc. どんなソースが⽣生成される? PHP_̲METHOD(Utils_̲Fib, calc) { zval *n_̲param =
NULL, *_̲0 = NULL, *_̲1 = NULL, *_̲2 = NULL; int n, ZEPHIR_̲LAST_̲CALL_̲STATUS; ZEPHIR_̲MM_̲GROW(); zephir_̲fetch_̲params(1, 1, 0, &n_̲param); n = zephir_̲get_̲intval(n_̲param); if (n < 2) { RETURN_̲MM_̲LONG(n);} ZEPHIR_̲INIT_̲VAR(_̲1); ZVAL_̲LONG(_̲1, (n -‐‑‒ 1)); ZEPHIR_̲CALL_̲SELF(&_̲0, "calc", NULL, 0, _̲1); zephir_̲check_̲call_̲status(); ZEPHIR_̲INIT_̲NVAR(_̲1); ZVAL_̲LONG(_̲1, (n -‐‑‒ 2)); ZEPHIR_̲CALL_̲SELF(&_̲2, "calc", NULL, 0, _̲1); zephir_̲check_̲call_̲status(); zephir_̲add_̲function(return_̲value, _̲0, _̲2); RETURN_̲MM(); } int型で⽐比較を ⾏行行っている
© Cygames, Inc. どんなソースが⽣生成される? PHP_̲METHOD(Utils_̲Fib, calc) { zval *n_̲param =
NULL, *_̲0 = NULL, *_̲1 = NULL, *_̲2 = NULL; int n, ZEPHIR_̲LAST_̲CALL_̲STATUS; ZEPHIR_̲MM_̲GROW(); zephir_̲fetch_̲params(1, 1, 0, &n_̲param); n = zephir_̲get_̲intval(n_̲param); if (n < 2) { RETURN_̲MM_̲LONG(n);} ZEPHIR_̲INIT_̲VAR(_̲1); ZVAL_̲LONG(_̲1, (n -‐‑‒ 1)); ZEPHIR_̲CALL_̲SELF(&_̲0, "calc", NULL, 0, _̲1); zephir_̲check_̲call_̲status(); ZEPHIR_̲INIT_̲NVAR(_̲1); ZVAL_̲LONG(_̲1, (n -‐‑‒ 2)); ZEPHIR_̲CALL_̲SELF(&_̲2, "calc", NULL, 0, _̲1); zephir_̲check_̲call_̲status(); zephir_̲add_̲function(return_̲value, _̲0, _̲2); RETURN_̲MM(); } intではなく、 ZVALで値の やり取りをしている
© Cygames, Inc. どんなソースが⽣生成される? PHP_̲METHOD(Utils_̲Fib, calc) { zval *n_̲param =
NULL, *_̲0 = NULL, *_̲1 = NULL, *_̲2 = NULL; int n, ZEPHIR_̲LAST_̲CALL_̲STATUS; ZEPHIR_̲MM_̲GROW(); zephir_̲fetch_̲params(1, 1, 0, &n_̲param); n = zephir_̲get_̲intval(n_̲param); if (n < 2) { RETURN_̲MM_̲LONG(n);} ZEPHIR_̲INIT_̲VAR(_̲1); ZVAL_̲LONG(_̲1, (n -‐‑‒ 1)); ZEPHIR_̲CALL_̲SELF(&_̲0, "calc", NULL, 0, _̲1); zephir_̲check_̲call_̲status(); ZEPHIR_̲INIT_̲NVAR(_̲1); ZVAL_̲LONG(_̲1, (n -‐‑‒ 2)); ZEPHIR_̲CALL_̲SELF(&_̲2, "calc", NULL, 0, _̲1); zephir_̲check_̲call_̲status(); zephir_̲add_̲function(return_̲value, _̲0, _̲2); RETURN_̲MM(); } 再帰部分の 関数コール
© Cygames, Inc. どんなソースが⽣生成される? PHP_̲METHOD(Utils_̲Fib, calc) { zval *n_̲param =
NULL, *_̲0 = NULL, *_̲1 = NULL, *_̲2 = NULL; int n, ZEPHIR_̲LAST_̲CALL_̲STATUS; ZEPHIR_̲MM_̲GROW(); zephir_̲fetch_̲params(1, 1, 0, &n_̲param); n = zephir_̲get_̲intval(n_̲param); if (n < 2) { RETURN_̲MM_̲LONG(n);} ZEPHIR_̲INIT_̲VAR(_̲1); ZVAL_̲LONG(_̲1, (n -‐‑‒ 1)); ZEPHIR_̲CALL_̲SELF(&_̲0, "calc", NULL, 0, _̲1); zephir_̲check_̲call_̲status(); ZEPHIR_̲INIT_̲NVAR(_̲1); ZVAL_̲LONG(_̲1, (n -‐‑‒ 2)); ZEPHIR_̲CALL_̲SELF(&_̲2, "calc", NULL, 0, _̲1); zephir_̲check_̲call_̲status(); zephir_̲add_̲function(return_̲value, _̲0, _̲2); RETURN_̲MM(); } ZVALなので intの⾜足し算も関数 コールになっている
© Cygames, Inc. Zephirでフィボナッチ数列列 • ZVALでの値のやりとり、関数コールもほぼ同 じようなのでそこまで⼤大きな差はでなかった • が、ほぼソース変えず⾼高速化 0
0.5 1 1.5 2 2.5 3 3.5 4 4.5 PHP Zephir 90%程度度に [s]
© Cygames, Inc. © Cygames, Inc. 70 もう少し実⽤用的なもの
© Cygames, Inc. Zephirでログ出⼒力力 • fwrite()でtsv形式でファイル出⼒力力 $fp = fopen($file, "a");
fwrite($fp, implode("¥t", $msg_̲arr).PHP_̲EOL); fclose($fp); public function write(string file, array msg_̲arr) { var fp = fopen(file, "a"); fwrite(fp, implode("¥t", msg_̲arr).PHP_̲EOL); fclose(fp); }
© Cygames, Inc. Zephirでログ出⼒力力 • fwrite()でtsv形式でファイル出⼒力力 • 単純な関数コールなので差は出にくい 0 10
20 30 40 50 60 PHP Zephir ほぼ変わらず [ms]
© Cygames, Inc. ZephirでNGワードチェック • NGワード配列列をループさせてstrpos()で検索索 • NGワードは50語 public $ng_̲list=
[“ダメな⾔言葉葉”,“いけない⾔言葉葉”,“やばい⾔言葉葉",…]; public function check($str) { foreach ($this-‐‑‒>ng_̲list as $key => $value) { if (strpos($str, $value) !== false) { $is_̲ng = true; //break; ⽐比較のためbreakはしない } } }
© Cygames, Inc. ZephirでNGワードチェック • NGワード配列列をループさせてstrpos()で検索索 • 配列列が⼤大きくなるほど改善あり • strpos()はZephir側で⾼高速化されている
0 0.05 0.1 0.15 0.2 0.25 0.3 0.35 0.4 PHP Zephir 約20%程度度に!! [ms]
© Cygames, Inc. ⼀一旦ここまでわかったこと • PHPとの互換性のためZVALでの計算など、 実質PHPがやっていることと同様の事を⾏行行って いる様⼦子。C⾔言語的に最適化の余地はある • 配列列処理理などループ処理理などは速くなる
• Zephirで標準関数のいくつか⾼高速化されている • PHPのコードをほぼ変えずに、Zephirの構⽂文 規則に整えればextension化ができる • 引数の型などはチェックは確実に⾏行行う • PHPだとwarningでもFATAL ERRORになる
© Cygames, Inc. 改めてZephir/extension化すること • Pros • ⾼高速化できる • PJ/FWなど関係なく利利⽤用可能
• 特定箇所のみに適応できる • PHPに戻すことも可能 • Cons • デプロイフローが増える • 修正がしにくい
© Cygames, Inc. 導⼊入箇所例例 • コード修正がほぼない共通処理理 • ループを多⽤用する箇所 • アプリ要件的に多⽤用される処理理
• Zephir側で⾼高速化された標準関数を多⽤用してい る箇所 • Library/Optimizers/以下
© Cygames, Inc. ⼀一部導⼊入してみた結果 • ゲームアプリで多い抽選処理理で⼀一部適応 • 2〜~6ms レスポンスタイムの改善
© Cygames, Inc. Zephirまとめ • やっぱり銀の弾丸はありませんでした(・∀・) • 条件さえ合えば影響範囲を絞って適応できる • ロールバックも可能
• ⽤用法と⽤用量量を守りつつ選択肢の⼀一つに
© Cygames, Inc. 全体まとめ • Cygamesは、 最⾼高のコンテンツを作りたいと思っています • それには⾼高速なトライ&エラーが⽋欠かせない •
同時に⾼高速なレスポンスも⽋欠かせない • それらを両⽴立立させるためPHPを使っています!