From 7c0faeeb6883c45dba7c3614d5739a127cb2c5a7 Mon Sep 17 00:00:00 2001 From: Shai Barack Date: Sat, 7 Jun 2025 19:46:06 -0700 Subject: [PATCH] Replace String.split() with precompiled regex String.split() will allocate and compile the given regex on every call. The networkstack process spends 2.8% of cycles doing this. https://pprof.corp.google.com/?id=%2Fcns%2Fpf-d%2Fhome%2Fandroid-telemetry-pitot-pprof-prod-data-owner%2Fstack_sampling_pprof%2F2025-06-07%2Fstack-sampling-pprof-6187fab4-56da-4842-b9c3-9d8db45801d1.pb.gz&metric=samples&filter=hide:%255Enterp_helper%2524,focus:regex%257Csplit&pivot=com.android.networkstack.com.android.net.module.util.ProcfsParsingUtils I randomly noticed this while looking at CPU profiles. Flag: EXEMPT refactor Test: ApfFilterTest and any others that may be exercising the code Change-Id: I811c0e8982a87d10fedcda93379b08e8ab38a11b --- .../android/net/module/util/ProcfsParsingUtils.java | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/staticlibs/device/com/android/net/module/util/ProcfsParsingUtils.java b/staticlibs/device/com/android/net/module/util/ProcfsParsingUtils.java index 44fc94121b..573bbb1aed 100644 --- a/staticlibs/device/com/android/net/module/util/ProcfsParsingUtils.java +++ b/staticlibs/device/com/android/net/module/util/ProcfsParsingUtils.java @@ -35,6 +35,7 @@ import java.nio.file.Files; import java.nio.file.Paths; import java.util.ArrayList; import java.util.List; +import java.util.regex.Pattern; public final class ProcfsParsingUtils { public static final String TAG = ProcfsParsingUtils.class.getSimpleName(); @@ -49,6 +50,8 @@ public final class ProcfsParsingUtils { private static final String IPV6_MCAST_PATH = "/proc/net/igmp6"; private static final String IPV4_DEFAULT_TTL_PATH = "/proc/sys/net/ipv4/ip_default_ttl"; + private static final Pattern WHITESPACE_PATTERN = Pattern.compile("\\s+"); + private ProcfsParsingUtils() { } @@ -129,7 +132,7 @@ public final class ProcfsParsingUtils { final List addresses = new ArrayList<>(); try { for (String line : lines) { - final String[] fields = line.split("\\s+"); + final String[] fields = WHITESPACE_PATTERN.split(line); if (!fields[1].equals(ifname)) { continue; } @@ -156,7 +159,7 @@ public final class ProcfsParsingUtils { @NonNull List lines, @NonNull String ifname) { final List addresses = new ArrayList<>(); for (String line: lines) { - final String[] fields = line.split("\\s+"); + final String[] fields = WHITESPACE_PATTERN.split(line); if (!fields[1].equals(ifname)) { continue; } @@ -182,7 +185,7 @@ public final class ProcfsParsingUtils { final List addresses = new ArrayList<>(); try { for (String line: lines) { - final String[] fields = line.split("\\s+"); + final String[] fields = WHITESPACE_PATTERN.split(line); if (!fields[1].equals(ifname)) { continue; } @@ -217,7 +220,7 @@ public final class ProcfsParsingUtils { String name = ""; // parse output similar to `ip maddr` command (iproute2/ip/ipmaddr.c#read_igmp()) for (String line : lines) { - final String[] parts = line.trim().split("\\s+"); + final String[] parts = WHITESPACE_PATTERN.split(line.trim()); if (!line.startsWith("\t")) { name = parts[1]; if (name.endsWith(":")) {