default LongWrapper add(LongWrapper other) { return () -> get() + other.get(); }
/* Result: 12,690 ±(99.9%) 0,148 s/op [Average] Statistics: (min, avg, max) = (12,281, 12,690, 12,784), stdev = 0,138 Confidence interval (99.9%): [12,543, 12,838] Samples, N = 15 mean = 12,690 ±(99.9%) 0,148 s/op min = 12,281 s/op p( 0,0000) = 12,281 s/op p(50,0000) = 12,717 s/op p(90,0000) = 12,784 s/op p(95,0000) = 12,784 s/op p(99,0000) = 12,784 s/op p(99,9000) = 12,784 s/op p(99,9900) = 12,784 s/op p(99,9990) = 12,784 s/op p(99,9999) = 12,784 s/op max = 12,784 s/op # Run complete. Total time: 00:06:26 Benchmark Mode Cnt Score Error Units ShakespearePlaysScrabbleWithRxJava.measureThroughput sample 15 12,690 ± 0,148 s/op Benchmark Mode Cnt Score Error Units ShakespearePlaysScrabbleWithRxJava.measureThroughput avgt 15 250074,776 ± 7736,734 us/op ShakespearePlaysScrabbleWithStreams.measureThroughput avgt 15 29389,903 ± 1115,836 us/op */ @Benchmark @BenchmarkMode(Mode.SampleTime) @OutputTimeUnit(TimeUnit.MILLISECONDS) @Warmup(iterations = 50) @Measurement(iterations = 50) @Fork(1) public List<Entry<Integer, List<String>>> measureThroughput() throws InterruptedException { // to compute the score of a given word Function<Integer, PublisherBase<Integer>> scoreOfALetter = letter -> PublisherBase.just(letterScores[letter - 'a']); // score of the same letters in a word Function<Entry<Integer, LongWrapper>, PublisherBase<Integer>> letterScore = entry -> PublisherBase.just( letterScores[entry.getKey() - 'a'] * Integer.min( (int) entry.getValue().get(), (int) scrabbleAvailableLetters[entry.getKey() - 'a'])); Function<String, PublisherBase<Integer>> toIntegerPublisherBase = string -> PublisherBase.fromIterable( IterableSpliterator.of(string.chars().boxed().spliterator())); // Histogram of the letters in a given word Function<String, PublisherBase<HashMap<Integer, LongWrapper>>> histoOfLetters = word -> toIntegerPublisherBase .apply(word) .collect( () -> new HashMap<Integer, LongWrapper>(), (HashMap<Integer, LongWrapper> map, Integer value) -> { LongWrapper newValue = map.get(value); if (newValue == null) { newValue = () -> 0L; } map.put(value, newValue.incAndSet()); }); // number of blanks for a given letter Function<Entry<Integer, LongWrapper>, PublisherBase<Long>> blank = entry -> PublisherBase.just( Long.max( 0L, entry.getValue().get() - scrabbleAvailableLetters[entry.getKey() - 'a'])); // number of blanks for a given word Function<String, PublisherBase<Long>> nBlanks = word -> histoOfLetters .apply(word) .flatMap(map -> PublisherBase.fromIterable(() -> map.entrySet().iterator())) .flatMap(blank) .reduce(Long::sum); // can a word be written with 2 blanks? Function<String, PublisherBase<Boolean>> checkBlanks = word -> nBlanks.apply(word).flatMap(l -> PublisherBase.just(l <= 2L)); // score taking blanks into account letterScore1 Function<String, PublisherBase<Integer>> score2 = word -> histoOfLetters .apply(word) .flatMap(map -> PublisherBase.fromIterable(() -> map.entrySet().iterator())) .flatMap(letterScore) .reduce(Integer::sum); // Placing the word on the board // Building the streams of first and last letters Function<String, PublisherBase<Integer>> first3 = word -> PublisherBase.fromIterable( IterableSpliterator.of(word.chars().boxed().limit(3).spliterator())); Function<String, PublisherBase<Integer>> last3 = word -> PublisherBase.fromIterable( IterableSpliterator.of(word.chars().boxed().skip(3).spliterator())); // Stream to be maxed Function<String, PublisherBase<Integer>> toBeMaxed = word -> PublisherBase.fromArray(first3.apply(word), last3.apply(word)) .flatMap(PublisherBase -> PublisherBase); // Bonus for double letter Function<String, PublisherBase<Integer>> bonusForDoubleLetter = word -> toBeMaxed.apply(word).flatMap(scoreOfALetter).reduce(Integer::max); // score of the word put on the board Function<String, PublisherBase<Integer>> score3 = word -> PublisherBase.fromArray( score2.apply(word), score2.apply(word), bonusForDoubleLetter.apply(word), bonusForDoubleLetter.apply(word), PublisherBase.just(word.length() == 7 ? 50 : 0)) .flatMap(PublisherBase -> PublisherBase) .reduce(Integer::sum); Function< Function<String, PublisherBase<Integer>>, PublisherBase<TreeMap<Integer, List<String>>>> buildHistoOnScore = score -> PublisherBase.fromIterable(() -> shakespeareWords.iterator()) .filter(scrabbleWords::contains) .filter(word -> checkBlanks.apply(word).blockingFirst()) .collect( () -> new TreeMap<Integer, List<String>>(Comparator.reverseOrder()), (TreeMap<Integer, List<String>> map, String word) -> { Integer key = score.apply(word).blockingFirst(); List<String> list = map.get(key); if (list == null) { list = new ArrayList<String>(); map.put(key, list); } list.add(word); }); // best key / value pairs List<Entry<Integer, List<String>>> finalList2 = buildHistoOnScore .apply(score3) .flatMap(map -> PublisherBase.fromIterable(() -> map.entrySet().iterator())) .take(3) .collect( () -> new ArrayList<Entry<Integer, List<String>>>(), (list, entry) -> { list.add(entry); }) .blockingFirst(); // System.out.println(finalList2); return finalList2; }