Migrate hot codepaths to formatSimple().

The recently added TextUtils.formatSimple() can efficiently format
simple strings, roughly 6.5x faster than using String.format().

This change starts using this new method in hot codepaths identified
from pprof traces, and this CL alone should reduce system_process CPU
usage by 0.24%.  Linked bug has detailed pprof screenshots.

Bug: 170978902
Test: atest FrameworksCoreTests:android.text.TextUtilsTest
Exempt-From-Owner-Approval: trivial refactoring
Change-Id: Ie5a21a24be6dfcdb29768fe235e20f050fc111c7
This commit is contained in:
Jeff Sharkey
2020-10-21 10:52:51 -06:00
parent c76708bc68
commit 305ef9e1cf
8 changed files with 18 additions and 12 deletions

View File

@@ -16,7 +16,7 @@
package android.service.notification;
import static android.app.NotificationChannel.PLACEHOLDER_CONVERSATION_ID;
import static android.text.TextUtils.formatSimple;
import android.annotation.NonNull;
import android.app.Notification;
@@ -31,8 +31,6 @@ import android.os.Build;
import android.os.Parcel;
import android.os.Parcelable;
import android.os.UserHandle;
import android.provider.Settings;
import android.text.TextUtils;
import com.android.internal.logging.InstanceId;
import com.android.internal.logging.nano.MetricsProto;
@@ -258,7 +256,7 @@ public class StatusBarNotification implements Parcelable {
@Override
public String toString() {
return String.format(
return formatSimple(
"StatusBarNotification(pkg=%s user=%s id=%d tag=%s key=%s: %s)",
this.pkg, this.user, this.id, this.tag,
this.key, this.notification);

View File

@@ -29,6 +29,7 @@ import android.provider.Settings;
import android.text.SpannableStringBuilder;
import android.text.Spanned;
import android.text.SpannedString;
import android.text.TextUtils;
import java.text.SimpleDateFormat;
import java.util.Calendar;
@@ -697,7 +698,7 @@ public class DateFormat {
}
private static String zeroPad(int inValue, int inMinDigits) {
return String.format(Locale.getDefault(), "%0" + inMinDigits + "d", inValue);
return TextUtils.formatSimple("%0" + inMinDigits + "d", inValue);
}
/**

View File

@@ -60,10 +60,9 @@ public final class LocalLog {
}
final String logLine;
if (mUseLocalTimestamps) {
logLine = String.format("%s - %s", LocalDateTime.now(), msg);
logLine = LocalDateTime.now() + " - " + msg;
} else {
logLine = String.format(
"%s / %s - %s", SystemClock.elapsedRealtime(), Instant.now(), msg);
logLine = SystemClock.elapsedRealtime() + " / " + Instant.now() + " - " + msg;
}
append(logLine);
}

View File

@@ -16,6 +16,8 @@
package com.android.internal.compat;
import static android.text.TextUtils.formatSimple;
import android.annotation.IntDef;
import android.util.Log;
import android.util.Slog;
@@ -175,7 +177,7 @@ public final class ChangeReporter {
}
private void debugLog(int uid, long changeId, int state) {
String message = String.format("Compat change id reported: %d; UID %d; state: %s", changeId,
String message = formatSimple("Compat change id reported: %d; UID %d; state: %s", changeId,
uid, stateToString(state));
if (mSource == SOURCE_SYSTEM_SERVER) {
Slog.d(TAG, message);

View File

@@ -853,6 +853,8 @@ public class TextUtilsTest {
@Test
public void testFormatSimple_Advanced() {
assertEquals("000000000000002a.ext",
formatSimple("%016x.%s", 42, "ext"));
assertEquals("crtcl=0x002a:intrsv=Y:grnk=0x0018:gsmry=A:example:rnk=0x0000",
formatSimple("crtcl=0x%04x:intrsv=%c:grnk=0x%04x:gsmry=%c:%s:rnk=0x%04x",
42, 'Y', 24, 'A', "example", 0));

View File

@@ -18,6 +18,7 @@ package com.android.server.am;
import static android.os.Process.ZYGOTE_POLICY_FLAG_EMPTY;
import static android.os.Process.ZYGOTE_POLICY_FLAG_LATENCY_SENSITIVE;
import static android.text.TextUtils.formatSimple;
import static com.android.server.am.ActivityManagerDebugConfig.*;
@@ -1892,7 +1893,7 @@ public final class BroadcastQueue {
}
private String createBroadcastTraceTitle(BroadcastRecord record, int state) {
return String.format("Broadcast %s from %s (%s) %s",
return formatSimple("Broadcast %s from %s (%s) %s",
state == BroadcastRecord.DELIVERY_PENDING ? "in queue" : "dispatched",
record.callerPackage == null ? "" : record.callerPackage,
record.callerApp == null ? "process unknown" : record.callerApp.toShortString(),

View File

@@ -17,6 +17,7 @@
package com.android.server.locksettings;
import static android.content.Context.USER_SERVICE;
import static android.text.TextUtils.formatSimple;
import static com.android.internal.annotations.VisibleForTesting.Visibility.PACKAGE;
import static com.android.internal.widget.LockPatternUtils.USER_FRP;
@@ -527,7 +528,7 @@ class LockSettingsStorage {
protected String getSynthenticPasswordStateFilePathForUser(int userId, long handle,
String name) {
final File baseDir = getSyntheticPasswordDirectoryForUser(userId);
final String baseName = String.format("%016x.%s", handle, name);
final String baseName = formatSimple("%016x.%s", handle, name);
return new File(baseDir, baseName).getAbsolutePath();
}

View File

@@ -15,6 +15,8 @@
*/
package com.android.server.notification;
import static android.text.TextUtils.formatSimple;
import android.annotation.NonNull;
import android.app.NotificationManager;
import android.content.Context;
@@ -138,7 +140,7 @@ public class RankingHelper {
boolean isGroupSummary = record.getNotification().isGroupSummary();
record.setGlobalSortKey(
String.format("crtcl=0x%04x:intrsv=%c:grnk=0x%04x:gsmry=%c:%s:rnk=0x%04x",
formatSimple("crtcl=0x%04x:intrsv=%c:grnk=0x%04x:gsmry=%c:%s:rnk=0x%04x",
record.getCriticality(),
record.isRecentlyIntrusive()
&& record.getImportance() > NotificationManager.IMPORTANCE_MIN