From 740710388b1a759a12938ad6ab9706bdf8723c81 Mon Sep 17 00:00:00 2001 From: Jan Sebechlebsky Date: Mon, 28 Nov 2022 19:05:23 +0100 Subject: [PATCH] Change contentEquals implementation to operate in O(n) time. Calling other.get(key) does binary search in the "other" instance to look up the key, but this is not necessary, since if the two instances are equal, they will contain same keys with same values in exact same order. The cl also does some other minor changes: * avoid unnecessary method calls / bounds check in contentEquals. * avoid unnecessary method calls / bounds check / autoboxing in contentHashCode. It's possible that some of these would be done by AOT / JIT optimizations, but they generally tend to have some cost in Java. Test: atest SparseArrayTest Bug: 260964842 Change-Id: I060ea39e85056a86e986a0fe61d153c18c234f4b --- core/java/android/util/SparseArray.java | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/core/java/android/util/SparseArray.java b/core/java/android/util/SparseArray.java index 05c8617294dab..cc83decc7b21c 100644 --- a/core/java/android/util/SparseArray.java +++ b/core/java/android/util/SparseArray.java @@ -525,9 +525,10 @@ public class SparseArray implements Cloneable { return false; } + // size() calls above took care about gc() compaction. for (int index = 0; index < size; index++) { - int key = keyAt(index); - if (!Objects.equals(valueAt(index), other.get(key))) { + if (mKeys[index] != other.mKeys[index] + || !Objects.equals(mValues[index], other.mValues[index])) { return false; } } @@ -545,10 +546,11 @@ public class SparseArray implements Cloneable { public int contentHashCode() { int hash = 0; int size = size(); + // size() call above took care about gc() compaction. for (int index = 0; index < size; index++) { - int key = keyAt(index); - E value = valueAt(index); - hash = 31 * hash + Objects.hashCode(key); + int key = mKeys[index]; + E value = (E) mValues[index]; + hash = 31 * hash + key; hash = 31 * hash + Objects.hashCode(value); } return hash;