A question arose while using querydsl.
I heard that using transform can be dangerous because it uses a lot of memory. However, if you don't use transform, you will use memory through something like a stream anyway, so I'm curious what the difference is between the two.
If the differences between the two are similar, wouldn't it be okay to just use transform?
使用querydsl时出现问题。我听说使用Transform可能很危险,因为它使用大量内存。但是,如果不使用Transform,无论如何都会通过流之类的方式使用内存,所以我很好奇这两者之间有什么不同。如果两者之间的差异相似,那么只使用Transform不就可以了吗?
For reference, the number of stores according to the results is about 10,000. Each store has about 3 keywords.
作为参考,根据结果计算的门店数量约为1万家。每家商店都有大约3个关键词。
"When using stream"
@Override
public Page<MyLikeStoreResponse> findMyLikeStore(Long memberId, Pageable pageable) {
List<Store> storeQuery =
jpaQueryFactory
.select(likes.store)
.from(likes)
.join(likes.store, store)
.join(likes.member, member)
.leftJoin(store.storeKeywordList, storeKeyword)
.leftJoin(storeKeyword.keyword, keyword)
.where(member.memberId.eq(memberId))
.offset(pageable.getOffset())
.limit(pageable.getPageSize())
.fetch();
List<MyLikeStoreResponse> response = createMyLikeStoreResponse(storeQuery);
int count = jpaQueryFactory
.select(store)
.from(likes)
.join(likes.store, store)
.join(likes.member, member)
.where(member.memberId.eq(memberId))
.fetch()
.size();
return new PageImpl<>(response, pageable, count);
}
private List<MyLikeStoreResponse> createMyLikeStoreResponse(List<Store> storeQuery){
return storeQuery
.stream()
.map(store ->
MyLikeStoreResponse
.builder()
.phone(store.getPhone())
.storeId(store.getStoreId())
.address(store.getAddress())
.storeName(store.getName())
.keywordList(store.getStoreKeywordList().stream()
.limit(3)
.map(storeKeyword -> storeKeyword.getKeyword().getName())
.collect(Collectors.toList()))
.build()
).collect(Collectors.toList());
}
Performance test - stream
Performance test results using visualVM (requests were sent about 10 times): https://i.stack.imgur.com/wymAz.png
使用VisualVM的性能测试结果(请求发送了大约10次):https://i.stack.imgur.com/wymAz.png
When using transform
@Override
public Page<MyLikeStoreResponse> findMyLikeStore(Long memberId, Pageable pageable) {
List<MyLikeStoreResponse> response = jpaQueryFactory
.select(likes.store)
.from(likes)
.join(likes.store, store)
.join(likes.member, member)
.leftJoin(store.storeImageList, image).fetchJoin()
.leftJoin(store.storeKeywordList, storeKeyword)
.leftJoin(storeKeyword.keyword, keyword)
.where(member.memberId.eq(memberId))
.offset(pageable.getOffset())
.limit(pageable.getPageSize())
.transform(groupBy(store.storeId).list(
Projections.constructor(
MyLikeStoreResponse.class,
store.storeId,
store.name.as("storeName"),
store.address,
store.phone,
list(storeKeyword.keyword.name).as("keywordList")
)
));
int count = jpaQueryFactory
.select(store)
.from(likes)
.join(likes.store, store)
.join(likes.member, member)
.where(member.memberId.eq(memberId))
.fetch()
.size();
return new PageImpl<>(response, pageable, count);
}
Performance test - transform
Performance test results using visualVM (requests were sent about 10 times):
https://i.stack.imgur.com/5Ide5.png
使用VisualVM的性能测试结果(请求发送了大约10次):https://i.stack.imgur.com/5Ide5.png
And the stream method is approximately 100ms faster (measured using Postman).
而流方法的速度大约快100ms(使用邮递员测量)。
question
- Did I conduct the performance test correctly? I think I sent too few requests.
- There seems to be no difference comparing stream and transform. Is my judgment correct?
- Is it the right choice to conduct performance testing of both? Can we conclude that the two are similar without testing?
- Why is stream faster? Is there a reason you are planning to go?
更多回答
我是一名优秀的程序员,十分优秀!