diff --git a/core/java/android/app/LoadedApk.java b/core/java/android/app/LoadedApk.java index 185884fab7533..1f3dfa729a92a 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 zipPaths = new ArrayList<>(); - final List 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 zipPaths = new ArrayList<>(10); + final List 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 71b53f1f42ae2..1c13962c7dfda 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(); }