Android NDK -测量阶乘时间

Android NDK - measure time for factorial

本文关键字:阶乘 时间 测量 NDK Android      更新时间:2023-10-16

我是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.");
}
}

我不知道哪里出错了,或者我错过了什么,或者其他什么。

谢谢你的帮助!

这种行为完全可以解释你的代码。你犯了一些错误。你可能知道3万!是一个很大的数字。

  • NDK:

    • 你正在使用一个单一的循环,做30k乘法-这发生得非常快
    • 你在大约20之后使用jlong(一个有限的64位signed int) !它会溢出,所以你的结果当然是错误的
  • Android:
    • BigInteger分配内存以存储您的无限数字。各项运算越来越难,乘法运算越来越复杂
    • 在循环中有打印(或者更糟的是,在UI上有SetText() !) -永远不要将它们包含在您的测量中,它们需要时间