実行時間を測定するには?|Android開発

      2016/11/08

Androidで実行時間を測定し、ログに出力するサンプル。

Java層

測定方法1

long start = System.currentTimeMillis();
// 処理
long end = System.currentTimeMillis();
Log.i("MyApplication", "performance " + (end - start) + " msec");

測定方法2

より精度が高い測定。

long start = System.nanoTime()
// 処理
long end = System.nanoTime();
Log.i("MyApplication", "performance " + (end - start) + " nsec");

Native(JNI)層

C/C++

#include 
#include 

static unsigned int getTime()
{
    struct timeval now_tv;
    if (0 != gettimeofday(&now_tv, NULL)) {
        return 0;
    }
    return (unsigned int)((now_tv.tv_sec * 1000000) + now_tv.tv_usec);
}

unsigned int times[2];
times[0] = getTime();
times[1] = getTime();
__android_log_print(ANDROID_LOG_INFO, "app", "DebugTime(%u usec)\n", times[1] - times[0]);

C++(制度の高い測定)

#include "windows.h"

class PerformanceCounter
{
public:
    PerformanceCounter(void);
    void preparation(void);
    void finish(void);
    void start(void);
    LONGLONG stop(void);

private:
    LONGLONG        systemQuadPart_;
    LARGE_INTEGER   startPerformanceCount_;
    LARGE_INTEGER   stopPerformanceCount_;
    DWORD           priorityClass_;
    int             threadPriority_;
};
#include "PerformanceCounter.h"

PerformanceCounter::PerformanceCounter(void)
{
    systemQuadPart_ = 0;
    threadPriority_ = 0;
    priorityClass_ = 0;
    LARGE_INTEGER frequency;
    bool ret = QueryPerformanceFrequency(&frequency);
    if (ret) {
        systemQuadPart_ = frequency.QuadPart;
    }
}

void PerformanceCounter::preparation(void)
{
    priorityClass_ = GetPriorityClass(GetCurrentProcess());
    threadPriority_ = GetThreadPriority(GetCurrentThread());
    SetPriorityClass(GetCurrentProcess(), REALTIME_PRIORITY_CLASS);
    SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_HIGHEST);
}

void PerformanceCounter::finish(void)
{
    SetThreadPriority(GetCurrentThread(), threadPriority_);
    SetPriorityClass(GetCurrentProcess(), priorityClass_);
    threadPriority_ = 0;
    priorityClass_ = 0;
}

void PerformanceCounter::start(void)
{
    QueryPerformanceCounter(&startPerformanceCount_);
}

/* return value is msec. */
LONGLONG PerformanceCounter::stop(void)
{
    // 周波数の差分が取得できる。
    // msec なので 1000倍.
    QueryPerformanceCounter(&stopPerformanceCount_);
    return ((stopPerformanceCount_.QuadPart - startPerformanceCount_.QuadPart) * 1000 / systemQuadPart_);
}

使い方は、preparation()start()stop()finish()
stop()の戻り値が測定結果。

systemQuadPart_には1秒間の周波数を設定。
開始時と停止時の周波数差分を1秒間の周波数で割ることで実行時間を算出している。

参考:MSDN QueryPerformanceCounter

 - Android , , ,