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

Happy My Life

日常とか技術とか

Android NDK利用時のオーバーヘッドは?(1.6 & TraceView編)

Android ndk TraceView

前回のエントリーについた、はてブのコメントで、TraceViewでの結果が知りたい、というリクエストが上っていたので、TraceViewを使って計測してみた。

というかその前にTraceViewを知らなかったので、まずはその解説から。

TraceViewとは

グラフィカルなログビュアーの事で、これを知る事でデバッグの助けや、どこで処理時間がかかっているかパフォーマンスを視覚的に確認できるツール。

TraceViewの詳細は別エントリーで解説するつもり(説明する量はそんなに多くはないが)

TraceView対応版

前回はシステム時刻を利用して時間計測を行ったが、それをTraceViewに対応させた。

package com.example.android.ndkbench;

import android.app.Activity;
import android.graphics.Point;
import android.os.Bundle;
import android.os.Debug;
import android.util.Log;
import android.widget.TextView;

public class MainActivity extends Activity {
    private TextView textView;
    private String TAG = this.getClass().getName();

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
    
        textView = (TextView)findViewById(R.id.textview);
    
        int cnt = 0;
        long loopcnt = 10000000;
    
        // javaで足し算
        long sum = 0;
        Debug.startMethodTracing("ndkbench1");
        for (int i = 0; i < loopcnt; i++){
            sum += 1;
        }
        Debug.stopMethodTracing();
        String text = " sum:"+sum+"n";

        // ダミーの呼出
        sum = 0;
        for (int i = 0; i < loopcnt; i++){
            sum += getInt();
        }
        text += "dummySUM:"+sum + "n";
        
        // int getInt()
        sum=0;
        Debug.startMethodTracing("ndkbench2");
        for (int i = 0; i < loopcnt; i++){
            sum += getInt();
        }
        Debug.stopMethodTracing();
        text += " sum:"+sum + "n";

        // int addInt()
        sum=0;
        Debug.startMethodTracing("ndkbench3");
        for (int i = 0; i < loopcnt; i++){
            sum += addInt(1,1);
        }
        Debug.stopMethodTracing();
        text += "sum:"+sum + "n";

        textView.setText(text);
    }
    
    public native int getInt();
    public native int addInt(int i,int j);

    static {
        System.loadLibrary("bench-jni");
    }
}

結果

これらの結果は、HTC Desire + Android 2.2(Froyo)での結果

ndkbench1

bench1-22

ndkbench2

bench2-22

ndkbench3

bench3-22

Android 1.6でもベンチマーク

JITでNDKの関数がinline化されている、とコメントがあったので、手元のGDDPhone(HT-03A相当) + Android 1.6(Donuts)でも試してみた。

利用したソースコードは先のものと全く同じ

bench1

bench1-16

bench2

bench2-16

bench3

bench3-16

結論(とそれにまつわる謎)

処理時間だけ比較してみると、こんな感じになった。


Froyo

計測エリア 処理時間
bench1 18875.428
bench2 3061.951
bench3 3066.589

Donuts

計測エリア 処理時間
bench1 15386.413
bench2 10581.513
bench3 10492.401

となった。以前の調査結果と異なりJavaによる演算より、NDKを利用したループによる演算の処理時間の方が早いという結果になったのだが。これはどう考えたらいいのだろう?

その他、これらの結果から読み取れる事があれば教えてください m(__)m