Date post: | 26-Jun-2015 |
Category: |
Technology |
Upload: | - |
View: | 20,608 times |
Download: | 0 times |
P●P を C# で書き直したら100 倍速くなった
++C++;
岩永 信之
開幕ネタバレ
PHP を C# で書き直したら100 倍速くなった
うそ、おおげさ、まぎらわしい
言語変えただけで 100 倍になったら苦労しない
参考までに : 性能 静的な言語※と動的な言語(一般論として)
平均的には 5 倍程度の差(静的な言語が速い) 文字列処理なんかだと差が出ない 数値計算だと 30 倍くらい開くことも
C# でも(時々実測する限り) dynamic 型を使うとスピードが 5 分の 1 くらいに
※ コンパイル(あるいは JIT )型の言語で、コンパイル時に型情報を使った最適化をかけるもの
言語を変えて 1 桁は変わるけど、 2 ケタはそうない正直、「 100 倍速い…」って言われて自分もビビった
正しくは
PHP を C# で書き直したら100 倍速くなった
自分が
要は、きっちり設計しなおしたから大まかに 2 ケタくらい速くなったのは本当
元 P●P
1 つの巨大なファイル 1 クラスで約 4,000 行 public フィールド数 50
1 つの switch 文で長さ 688 行、 case ラベル約 200 個
ログ取りや結果の出力までべた書き 文字列連結で、固定フォーマットで
とあるモジュールにて
巨大 switch もJump Table 化さ
れない?
HTML ソースコードを生成してる
(その用途しか想定してない)
参照局所性落とす
実装しなおし後 C# クラス化
1 クラス数フィールド switch 分岐解消(多態化)
債務分割 ゲーム ロジックだけ切り出し 出力用のフォーマットは別途行う
(今や元より高機能だけども)
同様の機能の実装(四角 1 つ 1 つが 1 クラス)
ちなみに : 書き換えの理由 理由もなく書き替えない
100 倍程度の速度差だと動機として弱い※
クライアント上でも同じロジック使うから
サバクラ両方で使うから C#
ちなみに、クライアントは iOS
サーバーも Mono にする†
† 「サーバー OS はそのまま Linux にするかも」という意味このモジュール以外は P●P のまま & 同一サーバー内実行
ネットワーク切れてもプレイしたい
クライアント上実装必須
チートされるとまずい
サーバー上実装必須
※ サーバー代金が問題になるような負荷でもなかったたぶん、データベース アクセスとかの方がよっぽどネック
その他の効能 整理されたことで
開発ペースはかなり速い(前はバグが 1 か月取れない※とかあった)
債務分割(ビューの切り離し)で コマンドライン デバッグ可能に (サーバー、クライアントはもちろん)
企画者向けのバランス検証ツールともコード共有化 他のゲームでも使う予定
※ かかる工数的に、直しても見合わないという判断ありバグを直すんじゃなくて、バグってるアイテムの出現確率を落として回避
ここまで前振り今日のテーマなんだっけ?
ここまで WinRT の話なし
ここからもあんまり
その他の効能(再) 整理されたことで
開発ペースはかなり速い(前はバグが 1 か月取れない※とかあった)
債務分割(ビューの切り離し)で コンソール デバッグ可能に (サーバー、クライアントはもちろん)
企画者向けのバランス検証ツールともコード共有化 他のゲームでも使う予定
これ
つまり こういう状態
主要機能
iOSクライアン
ト
Windowデスクトッ
プクライアン
ト
Linuxサーバー
デバッグ用コマンドライン
共有
Windowストア アプリ 今更 1 個増えたくら
いどうってことない※
※ ロジック担当の発言です。 UI担当の方ごめんなさい。
WinRTへの移行とか、何もやることない※
※ ロジック担当の発言です。 UI担当の方ごめんなさい。
ここからこころなし程度の WinRT
?!
実際にやったことの片鱗を 三択クイズ アプリ
実際に作ったものそのものではないものの、似た仕組みで実装
Windows ストア アプリでデモを
三択クイズ 制御フロー的にはこんなの
問題集問題選択
正誤判定
ループ
全問終了 No
合格判定
Yes
出題
回答
問題を表示
回答
答え答えを表示
OK 次の問題へ
結果結果を表示
ModelView
ポイント 1: Model はいろいろ使う
問題集問題選択
正誤判定
ループ
全問終了 No
合格判定
Yes
出題
回答
答え
次の問題へ
結果
Model• ゲーム本体• サーバー上でチート検証• プランナー向け調整ツール• デバッグはコマンドライン
で
用途
• iOS 、 Windows 、 Linux…
• GUI 、 CUI• 手動、自動
ポイント 2: 完全状況再現
問題集問題選択
正誤判定
ループ
全問終了 No
合格判定
Yes
出題
回答
答え
次の問題へ
結果
Model
乱数シード値を記録
• ユーザー回答を記録• 与えた値が同じなら、
完全に同じ実行結果
用途• チート検証• オンライン対戦• ゲーム途中での中断 / 再開
ポイント 3: View⇔Model往復
問題集問題選択
正誤判定
ループ
全問終了 No
合格判定
Yes
出題
回答
問題を表示
回答
答え答えを表示
OK 次の問題へ
結果結果を表示
ModelView双方向
制御フローの中断と再開が必要
制御フローは Model側が管理してる / すべき
ポイント 4: 非同期
問題集問題選択
正誤判定
ループ
全問終了 No
合格判定
Yes
出題
回答
問題を表示
回答
答え答えを表示
OK 次の問題へ
結果結果を表示
ModelView• ユーザー操作を待ったり• アニメーション終了を待った
り
I/O 処理タイマー処理=非同期
ポイント まとめ ポイント
View と Model の分離必須 制御フローは Model側で 完全状況再現 View と Model の双方向のやりとり ( Model側から見て) View は非同期
三択クイズごときですら、たやすくない うまく扱えれば、いろいろなゲームに応用可能
どういうものを作ったか
制御フローは Model側で 完全状況再現 View と Model の双方向のやりとり ( Model側から見て) View は非同期
制御フローの中断と再開 = イテレーター
非同期 = Task クラス
間を取り持つクラス
Model
View
Interaction Channel
Model イテレーター化
問題集問題選択
正誤判定
ループ
全問終了 No
合格判定
Yes
出題
回答
答え
次の問題へ
結果
Model
Model イテレーター化
int correctCount = 0;
foreach (var q in _questions){ var qm = new Q(q); yield return qm;
var isCorrect = qm.Response == q.AnswerIndex; if (isCorrect) correctCount++; yield return new A(isCorrect);}
var correctRate = correctCount / num;yield return new Result( correctRate, _acceptableRate);
問題選択
正誤判定
合格判定
出題
答え
結果
Interaction Channel View と Model をつなぐ部分
問題集問題選択
正誤判定
ループ
全問終了 No
合格判定
Yes
出題
回答
問題を表示
回答
答え答えを表示
OK 次の問題へ
結果結果を表示
ModelView
Interaction Channel View と Model をつなぐ部分
Model
View
public class Channel<TMessage>{ public Channel(IEnumerator<TMessage> coroutine) public Task RunAsync()
public void AddAsyncHandler(Func<T, Task<TR>> handler) where T : Tmessage}
Model の制御フロー(イテレーター)を登録
View は Task非同期で応答
実行
同期版( Func<T, TR> )もある
View Interaction Channel から来たメッセージを処理
Task非同期
出題
回答
問題を表示
回答
答え答えを表示
OK 次の問題へ
結果結果を表示
View
View Interaction Channel から来たメッセージを処理
Task非同期
channel.AddHandler<Q, int>(m =>{ Console.WriteLine(m.Question.Statement); int i = 1; foreach (var op in m.Question.Options) Console.WriteLine("{0}. {1}", i++, op);
Console.Write("何番? : "); int answer = int.Parse(Console.ReadLine(); return answer - 1;});
例 : 問題の表示と回答(コマンドライン版)問題文
選択肢
回答番号
結果 意外と汎用性高い
今日のデモ用の三択クイズ 実務で、 2系統のロジックをこれで実装 結構な種類のゲームがこの仕組みに乗る
残念なところ C# に型マッチング機能欲しい
型で分岐してる
アクター的機構も欲しい 他の言語のアクター機能も、使いやすいとは言い難いけど
ここまで WinRT の話なし( 再 )
ここからこころなし程度の WinRT
デモ コンソール版までは作ってあるんで じゃあ、ストア アプリ作ろうか
今から