Кэширование, как правило, быстрее для любых вычислений, которые даже несколько сложны, но есть компромисс. Кэшируя результаты своих вычислений, вы должны взять на себя некоторую ответственность за аннулирование кэша, когда результат вычисления более не точен. Возьмите следующий пример:
public class Rectangle
private int _height;
public int getHeight() {
return _height;
}
public void setHeight(int value) {
_height = value;
}
private int _width;
public int getWidth() {
return _width;
}
public void setWidth(int value) {
_width = value;
}
private int _area;
public int getArea() {
if (_area == 0) {
_area = _width * height;
}
return _area;
}
}
Здесь вычисление площади сохраняется, поэтому его не нужно пересчитывать (это немного тривиальный пример, и умножения на самом деле не являются достаточно дорогостоящими, чтобы оправдать кэширование, но вы получаете дрейф.). Следующий код работает нормально:
Rectangle r = new Rectangle();
r.setHeight(5);
r.setWidth(5);
r.getArea(); // returns 25.
Но если мы изменим какую-либо информацию, используемую для вычисления кэшированного элемента, в коде будет ошибка:
r.setHeight(3);
r.getArea(); // returns 25 - should be 15!
В этом случае решение простое - сбрасывайте область всякий раз, когда задается высота или ширина. Но если ваши вычисления становятся более сложными, вычисления зависят от чего-то, находящегося за пределами одного класса, или ваш механизм кэширования является более сложным, чем простая переменная-член, управление кэш-памятью может стать несколько проблематичным.
В общем, всякий раз, когда вы решите использовать кэширование, вы должны соблюдать осторожность и тщательно тестировать модуль, чтобы убедиться, что вы не вносите ошибок.