通过执行以下操作是否可以获得任何性能提升:
final int pixels = getResources.getDimensionPixelSize(R.dimen.pixels);
for (CustomView view: views) {
view.setPixelValue(pixels);
}
与
for (CustomView view: views) {
view.setPixelValue(getResources.getDimensionPixelSize(R.dimen.pixels));
}
还是缓存了dimens值/优化了字节码/使其变得多余的其他优化?
最佳答案
看Resources.getDimentionPixelSize()并深入到AssetManager.loadResourceValue()这是原生的,这是不可能的。但是,从Resources.getDimentionPixelSize()
来源可以说出以下内容:
public int getDimensionPixelSize(int id) throws NotFoundException {
synchronized (mAccessLock) {
TypedValue value = mTmpValue;
if (value == null) {
mTmpValue = value = new TypedValue();
}
getValue(id, value, true);
if (value.type == TypedValue.TYPE_DIMENSION) {
return TypedValue.complexToDimensionPixelSize(
value.data, mMetrics);
}
throw new NotFoundException(
"Resource ID #0x" + Integer.toHexString(id) + " type #0x"
+ Integer.toHexString(value.type) + " is not valid");
}
}
它将通过
synchronized (mAccessLock)
锁定资源(读取,如果您的某个其他线程将尝试在同一时间访问资源-其中一个将等待);它将在
TypedValue.complexToDimensionPixelSize()
内调用一些浮点数学;它可能会创建
TypedValue
对象;它将至少执行5次方法调用;
因此,也许它被缓存在本机中的某个地方,但是即使如此,呼叫对于您而言绝对不是免费的。
这是我针对此问题所做的一些测量(仅单线程访问资源):
int pixels = 0;
Resources res = getResources();
long ms = System.currentTimeMillis();
for (int i = 0; i < 100000; i++) {
pixels = res.getDimensionPixelSize(R.dimen.my_dimen);
}
Log.e(TAG, "Time " + (System.currentTimeMillis() - ms));
在装有Android Lollipop的S6上,它的通话时间约为816毫秒或8160纳秒。
最后,在您的情况下(我相信您最多可以进行10-20次迭代),性能确实无关紧要。在更多的迭代中和/或某些并发的资源访问可能很重要。
就个人而言,我建议您在外部进行此操作,以获得更好的样式和较小但仍可以提高速度的效果。