Use SparseArray for detached views.

Summary:
This is minor, but for our use case a SparseArray is going to be faster as long as we have less than 10,000 clipped subviews, and will also use much less memory.

Faster because of the boxing, unboxing and hash caching; less memory as it is two arrays instead of the object overhead of the HashMap.

Reviewed By: ahmedre

Differential Revision: D3704326
This commit is contained in:
Seth Kirby 2016-08-15 20:39:50 -07:00 committed by Ahmed El-Helw
parent b2f41e2921
commit a602891946
4 changed files with 14 additions and 10 deletions

View File

@ -163,7 +163,7 @@ import com.facebook.react.views.view.ReactClippingViewGroupHelper;
// less in our case because of the large constant overhead and auto boxing of the map.
private SparseIntArray mDrawViewIndexMap = StateBuilder.EMPTY_SPARSE_INT;
// Map of views that are currently clipped.
private final Map<Integer, View> mClippedSubviews = new HashMap<>();
private final SparseArray<View> mClippedSubviews = new SparseArray<>();
protected final Rect mClippingRect = new Rect();
@ -297,11 +297,11 @@ import com.facebook.react.views.view.ReactClippingViewGroupHelper;
}
private boolean isClipped(int id) {
return mClippedSubviews.containsKey(id);
return mClippedSubviews.get(id) != null;
}
private boolean isNotClipped(int id) {
return !mClippedSubviews.containsKey(id);
return mClippedSubviews.get(id) == null;
}
@Override
@ -510,8 +510,8 @@ import com.facebook.react.views.view.ReactClippingViewGroupHelper;
}
@Override
public Collection<View> getDetachedViews() {
return mClippedSubviews.values();
public SparseArray<View> getDetachedViews() {
return mClippedSubviews;
}
/**

View File

@ -15,6 +15,7 @@ import java.util.Collection;
import android.graphics.Canvas;
import android.graphics.Rect;
import android.util.SparseArray;
import android.util.SparseIntArray;
import android.view.View;
import android.view.ViewParent;
@ -78,7 +79,7 @@ import android.view.ViewParent;
*
* @return A collection of the currently detached views.
*/
abstract Collection<View> getDetachedViews();
abstract SparseArray<View> getDetachedViews();
/**
* Draw the relevant items. This should do as little work as possible.

View File

@ -15,6 +15,7 @@ import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import android.util.SparseArray;
import android.util.SparseIntArray;
import android.view.View;
import android.view.View.MeasureSpec;
@ -208,8 +209,9 @@ import com.facebook.react.uimanager.ViewManagerRegistry;
if (view instanceof FlatViewGroup) {
FlatViewGroup flatViewGroup = (FlatViewGroup) view;
if (flatViewGroup.getRemoveClippedSubviews()) {
Collection<View> detachedViews = flatViewGroup.getDetachedViews();
for (View detachedChild : detachedViews) {
SparseArray<View> detachedViews = flatViewGroup.getDetachedViews();
for (int i = 0, size = detachedViews.size(); i < size; i++) {
View detachedChild = detachedViews.valueAt(i);
// we can do super here because removeClippedSubviews is currently not recursive. if/when
// we become recursive one day, this should call vanilla dropView to be recursive as well.
super.dropView(detachedChild);

View File

@ -22,6 +22,7 @@ import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Rect;
import android.graphics.drawable.Drawable;
import android.util.SparseArray;
import android.util.SparseIntArray;
import android.view.MotionEvent;
import android.view.View;
@ -166,7 +167,7 @@ import com.facebook.react.views.view.ReactClippingViewGroup;
private long mLastTouchDownTime;
private @Nullable OnInterceptTouchEventListener mOnInterceptTouchEventListener;
private static final ArrayList<View> EMPTY_DETACHED_VIEWS = new ArrayList<>(0);
private static final SparseArray<View> EMPTY_DETACHED_VIEWS = new SparseArray<>(0);
// Provides clipping, drawing and node region finding logic if subview clipping is enabled.
private @Nullable DrawCommandManager mDrawCommandManager;
@ -778,7 +779,7 @@ import com.facebook.react.views.view.ReactClippingViewGroup;
*
* @return A Collection of Views to clean up.
*/
Collection<View> getDetachedViews() {
/* package */ SparseArray<View> getDetachedViews() {
if (mDrawCommandManager == null) {
return EMPTY_DETACHED_VIEWS;
}