在代码审查期间,我的一位同事看了这段代码:
public List<Item> extractItems(List<Object[]> results) {
return Lists.transform(results, new Function<Object[], Item>() {
@Override
public Item apply(Object[] values) {
...
}
});
}
他建议将其更改为:
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;
}
因此,我们正在考虑采用new Function()
构造,并将其移至成员变量并在下次重新使用。
虽然我理解他的逻辑和推理,但我想我没有卖掉我应该为我创建的每个可能的对象执行此操作。似乎有一些很好的理由不这样做,但我不确定。
你有什么想法?我们是否应该像这样缓存重复创建的对象?
更新
Function
是谷歌番石榴的东西,没有任何状态。有几个人指出了这种变化的非线程安全方面,这完全有效,但实际上并不是一个问题。我更多地询问构建vs缓存小对象的做法,哪个更好?
答案 0 :(得分:1)
您同事的提案不是线程安全的。它还充满了过早的优化。 Function
对象的构造是否已知(已测试)CPU瓶颈?如果没有,没有理由这样做。这不是一个记忆问题 - 你没有保留一个参考,所以GC会将它扫除,可能来自伊甸园。
答案 1 :(得分:0)
如前所述,这都是过早的优化。收益可能无法衡量,整个故事应该被遗忘。
然而,由于transformer
是无国籍的,我会因为可读性原因而选择它。匿名函数作为参数而非污染代码。
只需删除延迟初始化 - 无论何时使用该类,您都会使用transformer
,对吧? (*)所以把它放在static final
字段中,也许你可以在其他地方重复使用它。
(*)即使没有,在整个应用程序生命周期内创建并保存廉价对象也无关紧要。