summaryrefslogtreecommitdiff
path: root/core/java
diff options
context:
space:
mode:
authorAndreas Gampe <agampe@google.com>2016-05-18 11:58:39 -0700
committerAndreas Gampe <agampe@google.com>2016-05-18 15:48:12 -0700
commita8a58ffdeeb6a4a05de227a34972d99c005d2bf0 (patch)
tree6ec8c195d90d5665095ce9b209a6424994c13665 /core/java
parent6bd012a799f1dfd3d40dc3d581d18fb36618f0b1 (diff)
Frameworks/base: Optimize LoadedApk
Preallocate storage lists and avoid TextUtils and its string builder for a common code path. Optimize list join helper to not have a check in the loop. Bug: 28801010 Change-Id: Iafc582031f973d718252b34bcda6405a77425628
Diffstat (limited to 'core/java')
-rw-r--r--core/java/android/app/LoadedApk.java15
-rw-r--r--core/java/android/text/TextUtils.java11
2 files changed, 17 insertions, 9 deletions
diff --git a/core/java/android/app/LoadedApk.java b/core/java/android/app/LoadedApk.java
index 3f870005abfe..10566342325f 100644
--- a/core/java/android/app/LoadedApk.java
+++ b/core/java/android/app/LoadedApk.java
@@ -458,8 +458,14 @@ public final class LoadedApk {
}
}
- final List<String> zipPaths = new ArrayList<>();
- final List<String> libPaths = new ArrayList<>();
+ // Lists for the elements of zip/code and native libraries.
+ //
+ // Both lists are usually not empty. We expect on average one APK for the zip component,
+ // but shared libraries and splits are not uncommon. We expect at least three elements
+ // for native libraries (app-based, system, vendor). As such, give both some breathing
+ // space and initialize to a small value (instead of incurring growth code).
+ final List<String> zipPaths = new ArrayList<>(10);
+ final List<String> libPaths = new ArrayList<>(10);
makePaths(mActivityThread, mApplicationInfo, zipPaths, libPaths);
final boolean isBundledApp = mApplicationInfo.isSystemApp()
@@ -495,8 +501,11 @@ public final class LoadedApk {
/*
* With all the combination done (if necessary, actually create the java class
* loader and set up JIT profiling support if necessary.
+ *
+ * In many cases this is a single APK, so try to avoid the StringBuilder in TextUtils.
*/
- final String zip = TextUtils.join(File.pathSeparator, zipPaths);
+ final String zip = (zipPaths.size() == 1) ? zipPaths.get(0) :
+ TextUtils.join(File.pathSeparator, zipPaths);
if (ActivityThread.localLOGV)
Slog.v(ActivityThread.TAG, "Class path: " + zip +
diff --git a/core/java/android/text/TextUtils.java b/core/java/android/text/TextUtils.java
index 71b53f1f42ae..1c13962c7dfd 100644
--- a/core/java/android/text/TextUtils.java
+++ b/core/java/android/text/TextUtils.java
@@ -309,14 +309,13 @@ public class TextUtils {
*/
public static String join(CharSequence delimiter, Iterable tokens) {
StringBuilder sb = new StringBuilder();
- boolean firstTime = true;
- for (Object token: tokens) {
- if (firstTime) {
- firstTime = false;
- } else {
+ Iterator<?> it = tokens.iterator();
+ if (it.hasNext()) {
+ sb.append(it.next());
+ while (it.hasNext()) {
sb.append(delimiter);
+ sb.append(it.next());
}
- sb.append(token);
}
return sb.toString();
}