通过执行以下操作是否可以获得任何性能提升:

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次迭代),性能确实无关紧要。在更多的迭代中和/或某些并发的资源访问可能很重要。

就个人而言,我建议您在外部进行此操作,以获得更好的样式和较小但仍可以提高速度的效果。

10-05 23:56