summaryrefslogtreecommitdiffstats
path: root/benchmarks
diff options
context:
space:
mode:
authorNarayan Kamath <narayan@google.com>2014-12-24 13:44:58 +0000
committerNarayan Kamath <narayan@google.com>2014-12-30 10:42:07 +0000
commitfa080b83161fa8f2c538009b312d074dd17016bc (patch)
treedd98c87e3754c1fa3db3565465d3d485bccd2b26 /benchmarks
parentc3c69f0786877aec9c4cb1279f43dc35e668f273 (diff)
downloadlibcore-fa080b83161fa8f2c538009b312d074dd17016bc.zip
libcore-fa080b83161fa8f2c538009b312d074dd17016bc.tar.gz
libcore-fa080b83161fa8f2c538009b312d074dd17016bc.tar.bz2
Add a zero-copy path for Collections.sort() on ArrayList.
Given that ArrayLists are array backed, we can sort the underlying array in place. A similar optimisation can be applied to Vector and CopyOnWriteArrayList but vector isn't used often enough to slow everything else down with an instanceof check and nobody should be daft enough to try sorting a CopyOnWriteArrayList. Note that it's possible to apply the same optimisation to Collections.sort(List<T>, Comparator<? super T>) but it involves a larger refactoring to allow us to use Object[] instead of T[] and is accompanied by a general loss of readability. ArrayList performance improves for all array sizes : BEFORE Scenario{vm=app_process, trial=0, benchmark=Sort_arrayList, arrayListLength=4} 39021.26 ns; σ=206.27 ns @ 3 trials Scenario{vm=app_process, trial=0, benchmark=Sort_arrayList, arrayListLength=16} 120903.59 ns; σ=1188.88 ns @ 5 trials Scenario{vm=app_process, trial=0, benchmark=Sort_arrayList, arrayListLength=64} 435484.98 ns; σ=19141.88 ns @ 10 trials Scenario{vm=app_process, trial=0, benchmark=Sort_arrayList, arrayListLength=256} 1772876.81 ns; σ=5542.74 ns @ 3 trials Scenario{vm=app_process, trial=0, benchmark=Sort_arrayList, arrayListLength=1024} 7289431.83 ns; σ=110869.13 ns @ 10 trials AFTER Scenario{vm=app_process, trial=0, benchmark=Sort_arrayList, arrayListLength=4} 9161.79 ns; σ=90.04 ns @ 6 trials Scenario{vm=app_process, trial=0, benchmark=Sort_arrayList, arrayListLength=16} 29988.90 ns; σ=74.05 ns @ 3 trials Scenario{vm=app_process, trial=0, benchmark=Sort_arrayList, arrayListLength=64} 118142.86 ns; σ=1133.52 ns @ 7 trials Scenario{vm=app_process, trial=0, benchmark=Sort_arrayList, arrayListLength=256} 456091.11 ns; σ=9110.18 ns @ 10 trials Scenario{vm=app_process, trial=0, benchmark=Sort_arrayList, arrayListLength=1024} 1851939.39 ns; σ=69542.41 ns @ 10 trials For all other lists, there's no measurable difference for most sizes. length == 4 is harder to be sure about, given the large standard deviations and we'd expect the time spent in instanceof to be larger relative to the rest of what's going on. BEFORE Scenario{vm=app_process, trial=0, benchmark=Sort_vector, arrayListLength=4} 49002.02 ns; σ=1392.58 ns @ 10 trials Scenario{vm=app_process, trial=0, benchmark=Sort_vector, arrayListLength=16} 154967.88 ns; σ=332.29 ns @ 3 trials Scenario{vm=app_process, trial=0, benchmark=Sort_vector, arrayListLength=64} 588207.14 ns; σ=1863.60 ns @ 3 trials Scenario{vm=app_process, trial=0, benchmark=Sort_vector, arrayListLength=256} 2292967.79 ns; σ=4578.14 ns @ 3 trials Scenario{vm=app_process, trial=0, benchmark=Sort_vector, arrayListLength=1024} 9299582.60 ns; σ=179459.24 ns @ 10 trials AFTER Scenario{vm=app_process, trial=0, benchmark=Sort_vector, arrayListLength=4} 49324.98 ns; σ=240.86 ns @ 3 trials Scenario{vm=app_process, trial=0, benchmark=Sort_vector, arrayListLength=16} 155639.91 ns; σ=215.12 ns @ 3 trials Scenario{vm=app_process, trial=0, benchmark=Sort_vector, arrayListLength=64} 581950.81 ns; σ=938.11 ns @ 3 trials Scenario{vm=app_process, trial=0, benchmark=Sort_vector, arrayListLength=256} 2285933.64 ns; σ=13265.42 ns @ 3 trials Scenario{vm=app_process, trial=0, benchmark=Sort_vector, arrayListLength=1024} 8981475.84 ns; σ=431676.48 ns @ 10 trials bug: 18821961 Change-Id: I30a3eaf89ff478663f555c93556167107da10873
Diffstat (limited to 'benchmarks')
-rw-r--r--benchmarks/src/benchmarks/regression/CollectionsBenchmark.java55
1 files changed, 55 insertions, 0 deletions
diff --git a/benchmarks/src/benchmarks/regression/CollectionsBenchmark.java b/benchmarks/src/benchmarks/regression/CollectionsBenchmark.java
new file mode 100644
index 0000000..43d6d59
--- /dev/null
+++ b/benchmarks/src/benchmarks/regression/CollectionsBenchmark.java
@@ -0,0 +1,55 @@
+/*
+ * Copyright (C) 2014 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 benchmarks.regression;
+
+import com.google.caliper.Param;
+import com.google.caliper.SimpleBenchmark;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import java.util.Random;
+import java.util.Vector;
+
+public class CollectionsBenchmark extends SimpleBenchmark {
+ @Param({"4", "16", "64", "256", "1024"})
+ private int arrayListLength;
+
+ public void timeSort_arrayList(int nreps) {
+ List<Integer> input = buildList(arrayListLength, true /* use array list */);
+ for (int i = 0; i < nreps; ++i) {
+ Collections.sort(input);
+ }
+ }
+
+ public void timeSort_vector(int nreps) {
+ List<Integer> input = buildList(arrayListLength, false /* use array list */);
+ for (int i = 0; i < nreps; ++i) {
+ Collections.sort(input);
+ }
+ }
+
+ private static List<Integer> buildList(int arrayListLength, boolean useArrayList) {
+ Random random = new Random();
+ random.setSeed(0);
+ List<Integer> list = useArrayList ? new ArrayList<Integer>(arrayListLength) :
+ new Vector<Integer>(arrayListLength);
+ for (int i = 0; i < arrayListLength; ++i) {
+ list.add(random.nextInt());
+ }
+ return list;
+ }
+}