読者です 読者をやめる 読者になる 読者になる

WonderPlanet DEVELOPER BLOG

ワンダープラネットの開発者ブログです。モバイルゲーム開発情報を発信。

パーティクルの画像ファイルは plist に埋め込むべき?

おつかれさまです。藤澤です。
先日、弊社の新プロダクト クラッシュフィーバー の情報が公開、事前登録が開始されました。みなさま、よろしくおねがいいたします(宣伝)。

さて、現在そのクラッシュフィーバーの開発も佳境でして不具合修正やらレスポンスチューニングやらに追われているのですが、そんな中で標題の疑問が話題になったのでちょっと調べてみました。

※ 以下、Cocos2d-x 3.6 で確認しています。

パーティクルの画像ファイルは plist に埋め込むべき?

ほかは知りませんが、Cocos2d-x でパーティクルを扱う場合、パーティクルで使用するテクスチャを plist に埋め込むこともできますし、別ファイルとして用意することもできます。ですが両者に優劣はあるのでしょうか。

処理内容の比較

Cocos2d-x のソースを確認すると、パーティクルの読み込み処理は以下のようになっています。
1. textureFileName で指定されたファイルを読み込む。
2. ファイルが有効な画像であれば これをテクスチャとして使用する。
3. ファイルが読み込めなければ textureImageData で指定されたデータを Base64 デコード。
4. デコードしたデータを zlib で展開。
5. 展開したデータを画像として読み込む。
6. 有効な画像であればテクスチャとして使用する。
7. 画像として読み込めなければエラー。

したがって、テクスチャを plist に埋め込んだ場合、最初のファイル読み込みや Base64 デコード、zlib の解凍処理の分だけ余分な処理が行なわれていそうな気がします。
(なお、いずれの場合も TextureCache は使用されているようです)

では実際に このような 二種類のパーティクルを用意して比較してみます。
Fire1.plist はテクスチャを plist 内に埋め込んだもの、Fire2.plist はテクスチャを Smoke.png から読み込むようにしたものです。

ファイルサイズの比較

Fire1.plist は 9,713 byte
Fire2.plist + Smoke.png は 8,798 byte
Base64 エンコードしている分、plist に埋め込んだほうがサイズが大きくなってしまっているようです。

読み込み速度の比較

以下のようなコードで読み込み速度を比較してみます。

    std::vector<std::chrono::microseconds::rep> results;  
      
    for (int i = 0; i < 100; i++)  
    {  
        const auto start = std::chrono::system_clock::now();  
        ParticleSystemQuad *particle = ParticleSystemQuad::create("Fire1.plist");  
//        this->addChild(particle);  
        const auto end = std::chrono::system_clock::now();  
        auto result = std::chrono::duration_cast<std::chrono::microseconds>(end - start).count();  
        CCLOG("--- %d : %lld micro seconds", i, result);  
        results.push_back(result);  
    }  
      
    std::sort(results.begin(), results.end());  
    auto avg = std::accumulate(results.begin() + 1, results.end() - 1, 0) / (results.size() - 2);  
    CCLOG("--- avg : %lu", avg);  

パーティクルを 100 回読んでみて、初回の読み込み時間と、最大値・最小値を除いた中間値の平均を見てみます。
読み込み時間だけを見るため addChild は外しています。

手元の端末で試してみた結果は以下のとおりでした。(単位:マイクロ秒)

Fire1.plist(埋め込み)Fire2.plist(別ファイル)
iPhone シミュレータ(初回)99,63966,816
iPhone シミュレータ(平均)872440
iPhone 4(初回)249,522681,723
iPhone 4(平均)6,3603,402
android (SH-01E)(初回)486,494421,699
android (SH-01E)(平均)12,3738,964

概ね予想通りの結果ですが、iPhone 4 の初回読み込みのみ別ファイルのほうが若干遅くなっています。
PNG ファイルからの読み込みではデータ構造のチェックなども入るようなので、その分遅くなってしまっているのかもしれません。

というわけで、上記の結果を見ると多くの場合は別ファイルにしたほうが優れていそうですが、一部例外もあるので埋め込むべきか否かはケースバイケースということになりそうです。

今回は以上です。