2012-08-15 33 views
1

我正在編寫利用JNI的文本/ VoIP程序的C++/Native端。目前在C++端有三個函數可能會被Java代碼定期調用。功能被調用的頻率取決於用戶發送/接收文本消息的頻率以及他們的朋友在改變其存在/狀態方面的活躍程度。三個函數中的每一個都遵循下面的僞代碼,我不確定是否明智(甚至可能)在函數內「全局化」任何東西。JNI「優化」值得嗎?

JNIEnv *env; 
if (jvm_->GetEnv((void**) &env, JNI_VERSION_1_6) < 0) 
{ 
[print error and return] 
} 

jclass stringclass = env->FindClass("java/lang/String"); // Same for all 3 
jstring passinfo = env->NewStringUTF([str-info-to-pass]); // Different for all 3 
jclass cls = env->FindClass([directory to calling Java function class]); // Same for all 3 
[check if cls found, print error if not found and return] 

jmethodID methID = env->GetStatisMethodID([arguments for the function]); // Different for all 3 
[check if methID found, print error if not found and return] 

jobjectArray args = env->NewObjectArray([arguments to build argument structure being passed to function]); 
[call Java function, passing right arguments] 

我在想,我應該/將能夠在移動JCLASS stringclass,JCLASS CLS和JNIEnv的* ENV出來的功能,使他們的JNI_OnLoad函數調用期間設置的全局變量。這是可能的/可取的嗎?這些值與這些函數的OnLoad函數有什麼不同?我應該將它們實例化爲全局變量,並且每次都在函數調用中設置它們?而且,做任何這些都能真正提高性能,並且有顯着的提高?

回答

2

可能,是的。明智的,這取決於。爲自己定義什麼是「顯着的數量」。您期望JNI有哪些節奏?我認爲你可以看到緩存從每秒10+次以上開始會產生一些可衡量的影響。這是一個案子嗎?無論如何,以我個人的經驗,很好的緩存清理代碼,使其更短,更具可讀性。所以我會提出一些建議。

緩存結果FindClass,絕對是。一般來說,任何可重用和「靜態」的東西,你正在尋找的是一個符號名稱 - 它引入了符號查找的懲罰,與簡單地使用已經緩存的指針相反。 Liang JNI book也有關字段和方法ID的會談,因此您的GetStaticMethodID適用。 jmethodID比較簡單,因爲Get(Static)MethodID的結果可以直接進行緩存:它對任何進一步的調用都有效。與FindClass不同,它返回本地引用,所以爲了有效緩存(並使jmethodID真正持久),您必須從中創建NewGlobalRef - 並在適當時刪除它。 JNI_OnLoad tutorial中有一個很好的綜合示例。另一方面,JNIEnv緩存沒有意義,每次JNI調用都會得到它。緩存的JNIEnv也會無效,如果您碰巧從另一個線程調用了JNI方法而不是您緩存的那個線程。

+0

謝謝!不僅事情看起來運行得更快,而且代碼也更清晰。 – AeroBuffalo 2012-08-17 19:39:36

0

你不應該擔心表現。 目前我開發一個voip客戶端,我使用本地編解碼器。這意味着每個rtp數據包都會調用JNI(每20毫秒兩次,因爲編碼和解碼都是這樣),每次調用都會傳遞JNIEnv。這個變量只是一個指針。在這種情況下,對於我來說,在低端設備上JNI調用的CPU使用率低於1%,所以如果您只需要發短信,則不必擔心。