OSDN Git Service

Benchmarks for streams.
authorJeff Sharkey <jsharkey@android.com>
Thu, 12 Apr 2018 16:43:19 +0000 (10:43 -0600)
committerJeff Sharkey <jsharkey@android.com>
Thu, 12 Apr 2018 16:43:22 +0000 (10:43 -0600)
We've been advocating as little usage of streams as possible inside
the system_server, and this is a benchmark showing the costs of using
streams compared to rolling manual logic.

Results on a taimen show that direct route is 2.2x faster (!).

    Trial Report (1 of 2):
      Experiment {instrument=runtime, benchmarkMethod=timeDirect, vm=app_process, parameters={}}
      Results:
        runtime(ns): min=47234.28, 1st qu.=47234.28, median=47234.28, mean=47234.28, 3rd qu.=47234.28, max=47234.28
    Trial Report (2 of 2):
      Experiment {instrument=runtime, benchmarkMethod=timeStreams, vm=app_process, parameters={}}
      Results:
        runtime(ns): min=105660.39, 1st qu.=105660.39, median=105660.39, mean=105660.39, 3rd qu.=105660.39, max=105660.39

Bug: 77808546
Test: vogar --mode app_process --benchmark frameworks/base/core/tests/benchmarks/src/android/util/StreamsBenchmark.java
Change-Id: Iac43a75970eee2c91593316a1b5a45d2c96c476b

core/tests/benchmarks/src/android/util/StreamsBenchmark.java [new file with mode: 0644]

diff --git a/core/tests/benchmarks/src/android/util/StreamsBenchmark.java b/core/tests/benchmarks/src/android/util/StreamsBenchmark.java
new file mode 100644 (file)
index 0000000..a4f8abb
--- /dev/null
@@ -0,0 +1,114 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package android.util;
+
+import com.android.internal.util.FastPrintWriter;
+
+import com.google.caliper.AfterExperiment;
+import com.google.caliper.BeforeExperiment;
+
+import java.io.IOException;
+import java.io.OutputStream;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Comparator;
+import java.util.List;
+import java.util.Random;
+import java.util.stream.Collectors;
+
+public class StreamsBenchmark {
+    private OutputStream dummy = new OutputStream() {
+        @Override
+        public void write(int b) throws IOException {
+        }
+
+        @Override
+        public void write(byte b[], int off, int len) throws IOException {
+        }
+    };
+
+    private SparseIntArray calls;
+
+    @BeforeExperiment
+    protected void setUp() {
+        calls = new SparseIntArray();
+        final Random r = new Random(1);
+        for (int i = 0; i < 100; i++) {
+            calls.put(i, r.nextInt(Integer.MAX_VALUE));
+        }
+    }
+
+    @AfterExperiment
+    protected void tearDown() {
+        calls = null;
+    }
+
+    public void timeDirect(int reps) {
+        for (int i = 0; i < reps; i++) {
+            final int N = calls.size();
+            final long[] values = new long[N];
+            for (int j = 0; j < N; j++) {
+                values[j] = ((long) calls.valueAt(j) << 32) | calls.keyAt(j);
+            }
+            Arrays.sort(values);
+
+            final FastPrintWriter pw = new FastPrintWriter(dummy);
+            pw.println("Top openSession callers (uid=count):");
+            final int end = Math.max(0, N - 20);
+            for (int j = N - 1; j >= end; j--) {
+                final int uid = (int) (values[j] & 0xffffffff);
+                final int count = (int) (values[j] >> 32);
+                pw.print(uid);
+                pw.print("=");
+                pw.println(count);
+            }
+            pw.println();
+            pw.flush();
+        }
+    }
+
+    public void timeStreams(int reps) {
+        for (int i = 0; i < reps; i++) {
+            List<Pair<Integer, Integer>> callsList =
+                    getOpenSessionCallsList(calls).stream().sorted(
+                            Comparator.comparing(
+                                    (Pair<Integer, Integer> pair) -> pair.second).reversed())
+                    .limit(20)
+                    .collect(Collectors.toList());
+
+            final FastPrintWriter pw = new FastPrintWriter(dummy);
+            pw.println("Top openSession callers (uid=count):");
+            for (Pair<Integer, Integer> uidCalls : callsList) {
+                pw.print(uidCalls.first);
+                pw.print("=");
+                pw.println(uidCalls.second);
+            }
+            pw.println();
+            pw.flush();
+        }
+    }
+
+    private static List<Pair<Integer, Integer>> getOpenSessionCallsList(
+            SparseIntArray openSessionCalls) {
+        ArrayList<Pair<Integer, Integer>> list = new ArrayList<>(openSessionCalls.size());
+        for (int i=0; i<openSessionCalls.size(); i++) {
+            final int uid = openSessionCalls.keyAt(i);
+            list.add(new Pair<>(uid, openSessionCalls.get(uid)));
+        }
+
+        return list;
+    }
+}