Abh*_*kar 5 list microbenchmark java-8 java-stream jmh
我正在比较两种方法来过滤列表,使用和不使用流.事实证明,对于10,000个项目的列表,不使用流的方法更快.我有兴趣理解为什么会这样.有人能解释一下结果吗?
public static int countLongWordsWithoutUsingStreams(
final List<String> words, final int longWordMinLength) {
words.removeIf(word -> word.length() <= longWordMinLength);
return words.size();
}
public static int countLongWordsUsingStreams(final List<String> words, final int longWordMinLength) {
return (int) words.stream().filter(w -> w.length() > longWordMinLength).count();
}
Run Code Online (Sandbox Code Playgroud)
使用JMH的Microbenchmark:
@Benchmark
@BenchmarkMode(Throughput)
@OutputTimeUnit(MILLISECONDS)
public void benchmarkCountLongWordsWithoutUsingStreams() {
countLongWordsWithoutUsingStreams(nCopies(10000, "IAmALongWord"), 3);
}
@Benchmark
@BenchmarkMode(Throughput)
@OutputTimeUnit(MILLISECONDS)
public void benchmarkCountLongWordsUsingStreams() {
countLongWordsUsingStreams(nCopies(10000, "IAmALongWord"), 3);
}
public static void main(String[] args) throws RunnerException {
final Options opts = new OptionsBuilder()
.include(PracticeQuestionsCh8Benchmark.class.getSimpleName())
.warmupIterations(5).measurementIterations(5).forks(1).build();
new Runner(opts).run();
}
Run Code Online (Sandbox Code Playgroud)
java -jar target/benchmarks.jar -wi 5 -i 5 -f 1
基准
模式Cnt得分误差单位
PracticeQuestionsCh8Benchmark.benchmarkCountLongWordsUsingStreams thrpt 5 10.219 ±0.408 ops/ms
PracticeQuestionsCh8Benchmark.benchmarkCountLongWordsWithoutUsingStreams thrpt 5 910.785 ±21.215 ops/ms
编辑:(因为有人删除了作为答案发布的更新)
public class PracticeQuestionsCh8Benchmark {
private static final int NUM_WORDS = 10000;
private static final int LONG_WORD_MIN_LEN = 10;
private final List<String> words = makeUpWords();
public List<String> makeUpWords() {
List<String> words = new ArrayList<>();
final Random random = new Random();
for (int i = 0; i < NUM_WORDS; i++) {
if (random.nextBoolean()) {
/*
* Do this to avoid string interning. c.f.
* http://en.wikipedia.org/wiki/String_interning
*/
words.add(String.format("%" + LONG_WORD_MIN_LEN + "s", i));
} else {
words.add(String.valueOf(i));
}
}
return words;
}
@Benchmark
@BenchmarkMode(AverageTime)
@OutputTimeUnit(MILLISECONDS)
public int benchmarkCountLongWordsWithoutUsingStreams() {
return countLongWordsWithoutUsingStreams(words, LONG_WORD_MIN_LEN);
}
@Benchmark
@BenchmarkMode(AverageTime)
@OutputTimeUnit(MILLISECONDS)
public int benchmarkCountLongWordsUsingStreams() {
return countLongWordsUsingStreams(words, LONG_WORD_MIN_LEN);
}
}
public static int countLongWordsWithoutUsingStreams(
final List<String> words, final int longWordMinLength) {
final Predicate<String> p = s -> s.length() >= longWordMinLength;
int count = 0;
for (String aWord : words) {
if (p.test(aWord)) {
++count;
}
}
return count;
}
public static int countLongWordsUsingStreams(final List<String> words,
final int longWordMinLength) {
return (int) words.stream()
.filter(w -> w.length() >= longWordMinLength).count();
}
Run Code Online (Sandbox Code Playgroud)
每当您的基准测试表明超过10000个元素的某些操作需要1ns(编辑:1μs)时,您可能会发现一个聪明的JVM,确定您的代码实际上没有做任何事情.
Collections.nCopies实际上并没有列出10000个元素.它创建了一个带有1个元素的虚假列表,以及它应该存在多少次的计数.该列表也是不可变的,因此countLongWordsWithoutUsingStreams如果有事情removeIf要做,你会抛出异常.
| 归档时间: |
|
| 查看次数: |
3120 次 |
| 最近记录: |