Skip to content

Commit ac4a181

Browse files
Peter EliassonJohan Redestig
authored andcommitted
Improve performance when getting styled string.
The style used in the composing text for input methods takes a long time to create. This is experienced as a lag when composing the first word. The bottleneck lies in the 10 calls to nativeIndexOfString which does a linear search through thousands of strings. Change-Id: I3184b2be3673d384cca19e9a70ad94b4d3085576
1 parent 9de9342 commit ac4a181

File tree

2 files changed

+53
-48
lines changed

2 files changed

+53
-48
lines changed

core/java/android/content/res/StringBlock.java

Lines changed: 53 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -87,21 +87,48 @@ public CharSequence get(int idx) {
8787
if (style != null) {
8888
if (mStyleIDs == null) {
8989
mStyleIDs = new StyleIDs();
90-
mStyleIDs.boldId = nativeIndexOfString(mNative, "b");
91-
mStyleIDs.italicId = nativeIndexOfString(mNative, "i");
92-
mStyleIDs.underlineId = nativeIndexOfString(mNative, "u");
93-
mStyleIDs.ttId = nativeIndexOfString(mNative, "tt");
94-
mStyleIDs.bigId = nativeIndexOfString(mNative, "big");
95-
mStyleIDs.smallId = nativeIndexOfString(mNative, "small");
96-
mStyleIDs.supId = nativeIndexOfString(mNative, "sup");
97-
mStyleIDs.subId = nativeIndexOfString(mNative, "sub");
98-
mStyleIDs.strikeId = nativeIndexOfString(mNative, "strike");
99-
mStyleIDs.listItemId = nativeIndexOfString(mNative, "li");
100-
mStyleIDs.marqueeId = nativeIndexOfString(mNative, "marquee");
101-
102-
if (localLOGV) Log.v(TAG, "BoldId=" + mStyleIDs.boldId
103-
+ ", ItalicId=" + mStyleIDs.italicId
104-
+ ", UnderlineId=" + mStyleIDs.underlineId);
90+
}
91+
92+
// the style array is a flat array of <type, start, end> hence
93+
// the magic constant 3.
94+
for (int styleIndex = 0; styleIndex < style.length; styleIndex += 3) {
95+
int styleId = style[styleIndex];
96+
97+
if (styleId == mStyleIDs.boldId || styleId == mStyleIDs.italicId
98+
|| styleId == mStyleIDs.underlineId || styleId == mStyleIDs.ttId
99+
|| styleId == mStyleIDs.bigId || styleId == mStyleIDs.smallId
100+
|| styleId == mStyleIDs.subId || styleId == mStyleIDs.supId
101+
|| styleId == mStyleIDs.strikeId || styleId == mStyleIDs.listItemId
102+
|| styleId == mStyleIDs.marqueeId) {
103+
// id already found skip to next style
104+
continue;
105+
}
106+
107+
String styleTag = nativeGetString(mNative, styleId);
108+
109+
if (styleTag.equals("b")) {
110+
mStyleIDs.boldId = styleId;
111+
} else if (styleTag.equals("i")) {
112+
mStyleIDs.italicId = styleId;
113+
} else if (styleTag.equals("u")) {
114+
mStyleIDs.underlineId = styleId;
115+
} else if (styleTag.equals("tt")) {
116+
mStyleIDs.ttId = styleId;
117+
} else if (styleTag.equals("big")) {
118+
mStyleIDs.bigId = styleId;
119+
} else if (styleTag.equals("small")) {
120+
mStyleIDs.smallId = styleId;
121+
} else if (styleTag.equals("sup")) {
122+
mStyleIDs.supId = styleId;
123+
} else if (styleTag.equals("sub")) {
124+
mStyleIDs.subId = styleId;
125+
} else if (styleTag.equals("strike")) {
126+
mStyleIDs.strikeId = styleId;
127+
} else if (styleTag.equals("li")) {
128+
mStyleIDs.listItemId = styleId;
129+
} else if (styleTag.equals("marquee")) {
130+
mStyleIDs.marqueeId = styleId;
131+
}
105132
}
106133

107134
res = applyStyles(str, style, mStyleIDs);
@@ -119,17 +146,17 @@ protected void finalize() throws Throwable {
119146
}
120147

121148
static final class StyleIDs {
122-
private int boldId;
123-
private int italicId;
124-
private int underlineId;
125-
private int ttId;
126-
private int bigId;
127-
private int smallId;
128-
private int subId;
129-
private int supId;
130-
private int strikeId;
131-
private int listItemId;
132-
private int marqueeId;
149+
private int boldId = -1;
150+
private int italicId = -1;
151+
private int underlineId = -1;
152+
private int ttId = -1;
153+
private int bigId = -1;
154+
private int smallId = -1;
155+
private int subId = -1;
156+
private int supId = -1;
157+
private int strikeId = -1;
158+
private int listItemId = -1;
159+
private int marqueeId = -1;
133160
}
134161

135162
private CharSequence applyStyles(String str, int[] style, StyleIDs ids) {
@@ -403,6 +430,5 @@ private static final native int nativeCreate(byte[] data,
403430
private static final native int nativeGetSize(int obj);
404431
private static final native String nativeGetString(int obj, int idx);
405432
private static final native int[] nativeGetStyle(int obj, int idx);
406-
private static final native int nativeIndexOfString(int obj, String str);
407433
private static final native void nativeDestroy(int obj);
408434
}

core/jni/android_util_StringBlock.cpp

Lines changed: 0 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -147,25 +147,6 @@ static jintArray android_content_StringBlock_nativeGetStyle(JNIEnv* env, jobject
147147
return array;
148148
}
149149

150-
static jint android_content_StringBlock_nativeIndexOfString(JNIEnv* env, jobject clazz,
151-
jint token, jstring str)
152-
{
153-
ResStringPool* osb = (ResStringPool*)token;
154-
if (osb == NULL || str == NULL) {
155-
doThrow(env, "java/lang/NullPointerException");
156-
return 0;
157-
}
158-
159-
const char16_t* str16 = env->GetStringChars(str, NULL);
160-
jsize strLen = env->GetStringLength(str);
161-
162-
ssize_t idx = osb->indexOfString(str16, strLen);
163-
164-
env->ReleaseStringChars(str, str16);
165-
166-
return idx;
167-
}
168-
169150
static void android_content_StringBlock_nativeDestroy(JNIEnv* env, jobject clazz,
170151
jint token)
171152
{
@@ -193,8 +174,6 @@ static JNINativeMethod gStringBlockMethods[] = {
193174
(void*) android_content_StringBlock_nativeGetString },
194175
{ "nativeGetStyle", "(II)[I",
195176
(void*) android_content_StringBlock_nativeGetStyle },
196-
{ "nativeIndexOfString","(ILjava/lang/String;)I",
197-
(void*) android_content_StringBlock_nativeIndexOfString },
198177
{ "nativeDestroy", "(I)V",
199178
(void*) android_content_StringBlock_nativeDestroy },
200179
};

0 commit comments

Comments
 (0)