2

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?

1
  • 2
    The question here seems subjective, it's likely better placed on Code Review Exchange Commented May 14, 2014 at 16:09

2 Answers 2

3

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.

Sign up to request clarification or add additional context in comments.

3 Comments

Precisely what I was going to say. +1 for the thread safety. It's now marginally faster and substantially less safe to use!
The new Function() is google guava stuff, and holds no state, so even if two threads created two objects, and only the second stuck around, we don't much care. I almost put in the question to "ignore the non-thread-safety aspect of the change", but your points are valid for sure (I saw the same thing). My question is more aimed at "all things equal, is it better to save off the instances instead of recreate them each time".
@SeanAdkinson I'm sticking with premature optimization. You're trading less CPU usage for more memory usage without any idea if either is significant.
0

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.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.