Android NDK - 测量阶乘的时间

时间:2014-05-13 19:51:38

标签: java android c++ android-ndk

我是Android NDK编程的新手,但我想用Android NDK测量计算因子花费的时间,但它总是测量0或1或2ms,这很奇怪。

我的Android.mk文件如下所示:

LOCAL_PATH := $(call my-dir)
MY_PATH := $(LOCAL_PATH)
include $(call all-subdir-makefiles)

include $(CLEAR_VARS)  

LOCAL_PATH := $(MY_PATH)


LOCAL_LDLIBS := -llog

LOCAL_MODULE    := kru13_ndktest_NDKTestActivity
LOCAL_SRC_FILES := native.c  

include $(BUILD_SHARED_LIBRARY)

NDKTest.cpp看起来像这样:

#include <jni.h>
#include <stdio.h>


JNIEXPORT void JNICALL Java_kru13_ndktest_NDKTestActivity_helloLog(
        JNIEnv* env, jobject o, jlong n) {
        jlong faktorial = 1;
        jlong i;
        for(i=1; i<=n; i++){
            faktorial = faktorial * i;
        }
}

NDKTestActivity.java看起来像这样:

package kru13.ndktest;

import java.math.BigInteger;
import java.util.Date;

import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;

public class NDKTestActivity extends Activity implements OnClickListener{

public native static void helloLog(long n); 
Button vypocti;
EditText vstup;
TextView vysledek;
TextView vypocetjavy;
TextView vypocetndk;
BigInteger faktorial = BigInteger.valueOf(1);



static {  
    System.loadLibrary("kru13_ndktest_NDKTestActivity");  
}  


@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);

    vstup = (EditText) findViewById(R.id.editText1);
    vysledek = (TextView) findViewById(R.id.textView3);
    vypocetjavy = (TextView) findViewById(R.id.textView1);
    vypocetndk = (TextView) findViewById(R.id.textView2);
    vypocti = (Button) findViewById(R.id.button1);
    vypocti.setOnClickListener(new View.OnClickListener() {
        public void onClick(View v) {
            System.out.println("Button pressed.");

            Date zacatek = new Date();
            //Start Java calculating
            if (vstup.getText().toString().equals("")) vstup.setText("0");
            int num = Integer.parseInt(vstup.getText().toString());
            faktorial = BigInteger.valueOf(1);
            for(int i = 1; i<=num; i++){
                faktorial = faktorial.multiply(new BigInteger(i + ""));
            }
            vysledek.setText("");
            vysledek.setText("Result is: "+faktorial);
            Date konec = new Date();
            long rozdil = 0;
            rozdil = (konec).getTime() - zacatek.getTime();
            vypocetjavy.setText("");
            vypocetjavy.setText("Time with Java: "+rozdil+"ms.");
            //End Java calculating

            //Start NDK calculating
            Date zacatek2 = new Date();
            num = Integer.parseInt(vstup.getText().toString());
            helloLog(num);
            System.out.println(num);
            Date konec2 = new Date();
            long rozdil2 = 0;
            rozdil2 = (konec2).getTime() - zacatek2.getTime();
            vypocetndk.setText("");
            vypocetndk.setText("Time with NDK: "+rozdil2+"ms.");
            //End NDK calculating
        }
    });       
}

public void onClick(View V) {
    System.out.println("Button pressed.");
}
}

我不知道错误在哪里或错过了什么。

感谢您的帮助!

1 个答案:

答案 0 :(得分:0)

这种行为完全可以解释为您的代码。你有一些错误。你可能知道30k!是一个非常大的数字。

  • NDK

    • 你正在使用一个循环,进行30k次乘法 - 确实发生得非常快
    • 大约20岁后你正在使用jlong​​(有限的64位签名int)!它会溢出,所以你的结果当然是错误的
  • 机器人:

    • BigInteger分配内存以存储您的无限数字。每次操作越来越困难,乘法操作变得越来越复杂
    • 你在循环中打印(或者更糟糕的是,UI上的SetText()!) - 永远不要将它们包含在你的测量中,它们需要时间