From c5e9dcd3e60b585a901d57b8408400d3299f760a Mon Sep 17 00:00:00 2001 From: samiljan Date: Sat, 22 Sep 2012 12:50:21 +0200 Subject: [PATCH] Performance improvements --- .cproject | 2 +- jni/Application.mk | 5 +- jni/native.cpp | 4 +- .../aspellchecker/ASpellCheckerService.java | 82 ++++++++++++------- 4 files changed, 59 insertions(+), 34 deletions(-) diff --git a/.cproject b/.cproject index d313d12..57687a7 100644 --- a/.cproject +++ b/.cproject @@ -20,7 +20,7 @@ - + diff --git a/jni/Application.mk b/jni/Application.mk index 1f970c2..b222592 100644 --- a/jni/Application.mk +++ b/jni/Application.mk @@ -1,3 +1,4 @@ APP_STL := gnustl_static -APP_CPPFLAGS += -frtti -Wno-psabi -APP_OPTIM := debug +APP_OPTIM := release +APP_CPPFLAGS += -frtti -Wno-psabi -UNDEBUG +APP_ABI := armeabi-v7a \ No newline at end of file diff --git a/jni/native.cpp b/jni/native.cpp index c358604..05e7527 100644 --- a/jni/native.cpp +++ b/jni/native.cpp @@ -149,8 +149,8 @@ jobjectArray Java_se_randomdev_aspellchecker_ASpell_check(JNIEnv * env, jboolean isCopy; const char * word = env->GetStringUTFChars(wordStr, &isCopy); - __android_log_print(ANDROID_LOG_DEBUG, DEBUG_TAG, - "NDK:ASpell Checking word [%s]", word); + //__android_log_print(ANDROID_LOG_DEBUG, DEBUG_TAG, + // "NDK:ASpell Checking word [%s]", word); int have = aspell_speller_check(speller, word, -1); char code[5]; diff --git a/src/se/randomdev/aspellchecker/ASpellCheckerService.java b/src/se/randomdev/aspellchecker/ASpellCheckerService.java index a107330..aaf6fcc 100644 --- a/src/se/randomdev/aspellchecker/ASpellCheckerService.java +++ b/src/se/randomdev/aspellchecker/ASpellCheckerService.java @@ -10,14 +10,12 @@ import java.io.InputStream; import java.util.ArrayList; import java.util.Arrays; +import java.util.HashMap; import android.content.ContentResolver; -import android.content.SharedPreferences; import android.content.res.AssetManager; import android.database.ContentObserver; import android.database.Cursor; -import android.os.Handler; -import android.preference.PreferenceManager; import android.provider.ContactsContract.Contacts; import android.provider.UserDictionary.Words; import android.service.textservice.SpellCheckerService; @@ -34,7 +32,7 @@ public class ASpellCheckerService extends SpellCheckerService private static final String DATA = "data"; private static final String TAG = ASpellCheckerService.class.getSimpleName(); - private static final boolean DBG = true; + private static final boolean DBG = false; private static final String[] PROJECTION = { Words._ID, @@ -44,6 +42,19 @@ public class ASpellCheckerService extends SpellCheckerService Words.APP_ID }; + @Override + public void onCreate() + { + super.onCreate(); + Log.d(TAG,"ASpellCheckerService.onCreate"); + } + + @Override + public void onDestroy() + { + super.onDestroy(); + Log.d(TAG,"ASpellCheckerService.onDestroy"); + } @Override public Session createSession() @@ -103,8 +114,9 @@ private String checkAndUpdateDataFiles() throws IOException private static class ASpellCheckerSession extends Session { - private String mLocale; + private static String mLocale; private ASpell bridge; + private static ASpell sharedBridge; private String dataDir; private ContentResolver contentResolver; @@ -114,6 +126,8 @@ public ASpellCheckerSession(String dataDir, final ContentResolver contentResolve this.contentResolver = contentResolver; } + private HashMap cache = new HashMap(); + protected synchronized void UserDictionaryUpdated() { Cursor cursor = contentResolver.query(Words.CONTENT_URI, PROJECTION, @@ -143,16 +157,23 @@ protected synchronized void UserDictionaryUpdated() //Log.d(TAG, "User dictionary: "+ Arrays.toString(words.toArray(new String[]{}))); bridge.setUserDictionary(words.toArray(new String[]{})); + cache.clear(); } - + @Override public synchronized void onCreate() { - + if(getLocale().equals(mLocale)) + { + bridge = sharedBridge; + Log.d(TAG, "Reusing ASpell Speller. DataDir: "+dataDir+" Lang: "+mLocale); + return; + } mLocale = getLocale(); + Log.d(TAG, "Creating ASpell Speller. DataDir: "+dataDir+" Lang: "+mLocale); - bridge = new ASpell(dataDir,mLocale); + sharedBridge = bridge = new ASpell(dataDir,mLocale); contentResolver.registerContentObserver(Words.CONTENT_URI, true, new ContentObserver(null) { @Override @@ -166,36 +187,39 @@ public void onChange(boolean selfChange) { @Override public synchronized SuggestionsInfo onGetSuggestions(TextInfo textInfo, int suggestionsLimit) { - mLocale = getLocale(); + if(bridge == null) + return null; + String text = textInfo.getText(); - long start = System.currentTimeMillis(); - String []suggestions = bridge.check(text); - long end = System.currentTimeMillis(); - String code = suggestions[0]; - Log.d(TAG, "===Suggestion code ==> "+code); - - if(suggestions.length>1) // we have some suggestions + String [] suggestions; + long start = 0, end = 0; + + if(cache.containsKey(text)) { + suggestions = cache.get(text); + } + else + { + start = System.currentTimeMillis(); + suggestions = bridge.check(text); + end = System.currentTimeMillis(); + if(suggestions.length>suggestionsLimit+1) { - String []tmp = new String[suggestionsLimit]; - System.arraycopy(suggestions, 1, tmp, 0, suggestionsLimit); - suggestions = tmp; - } - else // just keep all suggestions - { - String []tmp = new String[suggestions.length-1]; - System.arraycopy(suggestions, 1, tmp, 0, tmp.length); - suggestions = tmp; + suggestions = Arrays.copyOf(suggestions, suggestionsLimit+1); } + + cache.put(text, suggestions); } - else{ - suggestions = new String[]{}; - } + + String code = suggestions[0]; + Log.d(TAG, "===Suggestion code ==> "+code); + + suggestions = Arrays.copyOfRange(suggestions, 1, suggestions.length); if (DBG) { - Log.d(TAG, "["+mLocale+"].onGetSuggestions ("+textInfo.getText()+","+suggestionsLimit+"): " + " Code : "+code+". Time to ASPELL: "+(end-start)+" ms."); + Log.d(TAG, "["+getLocale()+"].onGetSuggestions ("+textInfo.getText()+","+suggestionsLimit+"): " + " Code : "+code+". Time to ASPELL: "+(end-start)+" ms."); } int flags; if("1".equals(code) || suggestions.length > 0 && suggestions[0].equals(text))// Aspell bug?