Reputation: 8605
During code review, a colleague of mine looked at this piece of code:
public List<Item> extractItems(List<Object[]> results) {
return Lists.transform(results, new Function<Object[], Item>() {
@Override
public Item apply(Object[] values) {
...
}
});
}
He suggests changing it to this:
public List<Item> extractItems(List<Object[]> results) {
return Lists.transform(results, getTransformer());
}
private Function<Object[], Item> transformer;
private Function<Object[], Item> getTransformer() {
if(transformer == null) {
transformer = new Function<Object[], Item>() {
@Override
public Item apply(Object[] values) {
...
}
};
}
return transformer;
}
So we are looking at taking the new Function()
construction, and moving it over to be a member variable and re-used next time.
While I understand his logic and reasoning, I guess I'm not sold that I should do this for every possible object that I create that follows this pattern. It seems like there would be some good reasons not to do this, but I'm not sure.
What are your thoughts? Should we always cache duplicately created objects like this?
UPDATE
The Function
is a google guava thing, and holds no state. A couple people have pointed out the non-thread-safe aspect of this change, which is perfectly valid, but isn't actually a concern here. I'm more asking about the practice of constructing vs caching small objects, which is better?
Upvotes: 2
Views: 430
Reputation: 46422
As already said, it's all premature optimization. The gain is probably not measurable and the whole story should be forgotten.
However, with the transformer
being stateless, I'd go for it for readability reasons. Anonymous functions as an argument rather pollute the code.
Just drop the lazy initialization - you're gonna use the transformer
whenever you use the class, right? (*) So put it in a static final
field and maybe you can reuse it somewhere else.
(*) And even if not, creating and holding a cheap object during the whole application lifetime doesn't matter.
Upvotes: 0
Reputation: 13682
Your colleague's proposal is not thread safe. It also reeks of premature optimization. Is the construction of a Function
object a known (tested) CPU bottleneck? If not, there's no reason to do this. It's not a memory problem - you're not keeping a reference, so GC will sweep it away, probably from Eden.
Upvotes: 3