【发布时间】:2017-07-10 23:09:48
【问题描述】:
哪个更快?添加到foreach 中的列表或stream 中的映射和收集。
//Solution 1
List<Card> cards = mobileUserService.getCurrentUser().getUserCard();
final List<CardDTO> dtos = new ArrayList<>(cards.size());
cards.forEach(card -> dtos.add(cardTransformer.transform(card)));
或
//Solution 2
List<Card> cards = mobileUserService.getCurrentUser().getUserCard();
List<CardDTO> dtos = cards.stream()
.map(cardTransformer::transform)
.collect(Collectors.toList());
基准测试:
在大多数情况下,foreach 似乎更快。
测试代码变体1:
List<Card> cards = new ArrayList<>();
for (int i = 0; i < count; i++) {
Card c = Card.createFakeCard();
cards.add(c);
}
long startTime1 = System.nanoTime();
//Solution 1
final List<CardDTO> dtos = new ArrayList<>(cards.size());
cards.forEach(card -> dtos.add(cardTransformer.transform(card)));
long endTime1 = System.nanoTime();
long startTime2 = System.nanoTime();
//Solution 2
List<CardDTO> dtos2 = cards.stream()
.map(cardTransformer::transform)
.collect(Collectors.toList());
long endTime2 = System.nanoTime();
double runtime1 = (endTime1 - startTime1) / Math.pow(10, 6);
double runtime2 = (endTime2 - startTime2) / Math.pow(10, 6);
log.error("Number of elements: " + count + "\n" +
"Solution 1 " +
"Total time (ms): " + runtime1 + "\n" +
"Solution 2 " +
"Total time (ms): " + runtime2);
结果变体 1:
Number of elements: 1
Solution 1 Total time (ms): 3.862259
Solution 2 Total time (ms): 8.919641
Number of elements: 1
Solution 1 Total time (ms): 0.012556
Solution 2 Total time (ms): 0.032712
Number of elements: 1
Solution 1 Total time (ms): 0.011565
Solution 2 Total time (ms): 0.034363
Number of elements: 2
Solution 1 Total time (ms): 0.01619
Solution 2 Total time (ms): 0.03965
Number of elements: 10
Solution 1 Total time (ms): 0.020486
Solution 2 Total time (ms): 0.044607
Number of elements: 100
Solution 1 Total time (ms): 0.395842
Solution 2 Total time (ms): 0.729233
Number of elements: 1000
Solution 1 Total time (ms): 0.276229
Solution 2 Total time (ms): 0.37866
Number of elements: 5000
Solution 1 Total time (ms): 0.987951
Solution 2 Total time (ms): 1.092693
Number of elements: 10000
Solution 1 Total time (ms): 2.701169
Solution 2 Total time (ms): 3.287001
Number of elements: 20000
Solution 1 Total time (ms): 11.095115
Solution 2 Total time (ms): 11.3046
Number of elements: 50000
Solution 1 Total time (ms): 4.339383
Solution 2 Total time (ms): 6.235984
Number of elements: 100000
Solution 1 Total time (ms): 8.312332
Solution 2 Total time (ms): 9.088485
测试代码变体 2:
List<Card> cards = new ArrayList<>();
for (int i = 0; i < count; i++) {
Card c = Card.createFakeCard();
cards.add(c);
}
long startTime2 = System.nanoTime();
//Solution 2
List<CardDTO> dtos2 = cards.stream()
.map(cardTransformer::transform)
.collect(Collectors.toList());
long endTime2 = System.nanoTime();
long startTime1 = System.nanoTime();
//Solution 1
final List<CardDTO> dtos = new ArrayList<>(cards.size());
cards.forEach(card -> dtos.add(cardTransformer.transform(card)));
long endTime1 = System.nanoTime();
double runtime1 = (endTime1 - startTime1) / Math.pow(10, 6);
double runtime2 = (endTime2 - startTime2) / Math.pow(10, 6);
log.error("Number of elements: " + count + "\n" +
"Solution 1 " +
"Total time (ms): " + runtime1 + "\n" +
"Solution 2 " +
"Total time (ms): " + runtime2);
结果变体 2:
Number of elements: 1
Solution 1 Total time (ms): 1.672247
Solution 2 Total time (ms): 9.868603
Number of elements: 1
Solution 1 Total time (ms): 0.005617
Solution 2 Total time (ms): 0.043946
Number of elements: 1
Solution 1 Total time (ms): 0.005618
Solution 2 Total time (ms): 0.040971
Number of elements: 2
Solution 1 Total time (ms): 0.006278
Solution 2 Total time (ms): 0.041963
Number of elements: 10
Solution 1 Total time (ms): 0.011564
Solution 2 Total time (ms): 0.045929
Number of elements: 100
Solution 1 Total time (ms): 0.065093
Solution 2 Total time (ms): 0.121263
Number of elements: 1000
Solution 1 Total time (ms): 0.65555
Solution 2 Total time (ms): 0.968456
Number of elements: 5000
Solution 1 Total time (ms): 0.779127
Solution 2 Total time (ms): 1.244686
Number of elements: 10000
Solution 1 Total time (ms): 2.03769
Solution 2 Total time (ms): 2.337048
Number of elements: 20000
Solution 1 Total time (ms): 6.12232
Solution 2 Total time (ms): 6.038063
Number of elements: 50000
Solution 1 Total time (ms): 6.12232
Solution 2 Total time (ms): 8.463334
Number of elements: 100000
Solution 1 Total time (ms): 16.468047
Solution 2 Total time (ms): 17.86109
【问题讨论】:
-
您的基准测试结果如何?
-
为了更具声明性,您可以将
map(card -> cardTransformer.transform(card))替换为map(cardTransformer::transform) -
您认为有显着差异吗?如果是,为什么?
-
基准测试的问题在于它们总是给出答案,但答案并不一定意味着什么。像这样的基准(运行几次并使用
nanoTime()测量)通常毫无价值。但最重要的是,不要再担心微性能问题(这些问题确实存在),而是将所有这些大脑周期应用到编写清晰、可维护的代码上。您将获得更好的投资回报。
标签: java foreach java-8 java-stream