Implement cascasing checks via bitwise flags

It turns the spacing resolution in Java is fairly expensive right now
because it doesn't a bunch of unnecessary checks in the array,
especially when the Spacing instance doesn't have any values set on it.

This diff changes Spacing to store the state of the defined values in a
bitwise flag so that padding/border/margin queries are a lot faster
during layout calculations. This gives us as extra 20% performance win
in my local benchmarks on Android
This commit is contained in:
Lucas Rocha
2015-09-13 09:41:50 +01:00
parent ebc56fee59
commit cf94d35b51

View File

@@ -55,8 +55,22 @@ public class Spacing {
*/ */
public static final int ALL = 8; public static final int ALL = 8;
private static final int[] sFlagsMap = {
1, /*LEFT*/
2, /*TOP*/
4, /*RIGHT*/
8, /*BOTTOM*/
16, /*VERTICAL*/
32, /*HORIZONTAL*/
64, /*START*/
128, /*END*/
256, /*ALL*/
};
private final float[] mSpacing = newFullSpacingArray(); private final float[] mSpacing = newFullSpacingArray();
@Nullable private float[] mDefaultSpacing = null; @Nullable private float[] mDefaultSpacing = null;
private int mValueFlags = 0;
private boolean mHasAliasesSet;
/** /**
* Set a spacing value. * Set a spacing value.
@@ -70,6 +84,18 @@ public class Spacing {
public boolean set(int spacingType, float value) { public boolean set(int spacingType, float value) {
if (!FloatUtil.floatsEqual(mSpacing[spacingType], value)) { if (!FloatUtil.floatsEqual(mSpacing[spacingType], value)) {
mSpacing[spacingType] = value; mSpacing[spacingType] = value;
if (CSSConstants.isUndefined(value)) {
mValueFlags &= ~sFlagsMap[spacingType];
} else {
mValueFlags |= sFlagsMap[spacingType];
}
mHasAliasesSet =
(mValueFlags & sFlagsMap[ALL]) != 0 ||
(mValueFlags & sFlagsMap[VERTICAL]) != 0 ||
(mValueFlags & sFlagsMap[HORIZONTAL]) != 0;
return true; return true;
} }
return false; return false;
@@ -100,18 +126,28 @@ public class Spacing {
* @param spacingType one of {@link #LEFT}, {@link #TOP}, {@link #RIGHT}, {@link #BOTTOM} * @param spacingType one of {@link #LEFT}, {@link #TOP}, {@link #RIGHT}, {@link #BOTTOM}
*/ */
public float get(int spacingType) { public float get(int spacingType) {
int secondType = spacingType == TOP || spacingType == BOTTOM ? VERTICAL : HORIZONTAL; float defaultValue = (mDefaultSpacing != null)
float defaultValue = spacingType == START || spacingType == END ? CSSConstants.UNDEFINED : 0; ? mDefaultSpacing[spacingType]
return : (spacingType == START || spacingType == END ? CSSConstants.UNDEFINED : 0);
!CSSConstants.isUndefined(mSpacing[spacingType])
? mSpacing[spacingType] if (mValueFlags == 0) {
: !CSSConstants.isUndefined(mSpacing[secondType]) return defaultValue;
? mSpacing[secondType] }
: !CSSConstants.isUndefined(mSpacing[ALL])
? mSpacing[ALL] if ((mValueFlags & sFlagsMap[spacingType]) != 0) {
: mDefaultSpacing != null return mSpacing[spacingType];
? mDefaultSpacing[spacingType] }
: defaultValue;
if (mHasAliasesSet) {
int secondType = spacingType == TOP || spacingType == BOTTOM ? VERTICAL : HORIZONTAL;
if ((mValueFlags & sFlagsMap[secondType]) != 0) {
return mSpacing[secondType];
} else if ((mValueFlags & sFlagsMap[ALL]) != 0) {
return mSpacing[ALL];
}
}
return defaultValue;
} }
/** /**
@@ -132,7 +168,7 @@ public class Spacing {
*/ */
float getWithFallback(int spacingType, int fallbackType) { float getWithFallback(int spacingType, int fallbackType) {
return return
!CSSConstants.isUndefined(mSpacing[spacingType]) (mValueFlags & sFlagsMap[spacingType]) != 0
? mSpacing[spacingType] ? mSpacing[spacingType]
: get(fallbackType); : get(fallbackType);
} }