10888a09821a98ac0680fad765217302858e70fa4Paul Duffin/*
20888a09821a98ac0680fad765217302858e70fa4Paul Duffin * Copyright (C) 2014 The Guava Authors
30888a09821a98ac0680fad765217302858e70fa4Paul Duffin *
40888a09821a98ac0680fad765217302858e70fa4Paul Duffin * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
50888a09821a98ac0680fad765217302858e70fa4Paul Duffin * in compliance with the License. You may obtain a copy of the License at
60888a09821a98ac0680fad765217302858e70fa4Paul Duffin *
70888a09821a98ac0680fad765217302858e70fa4Paul Duffin * http://www.apache.org/licenses/LICENSE-2.0
80888a09821a98ac0680fad765217302858e70fa4Paul Duffin *
90888a09821a98ac0680fad765217302858e70fa4Paul Duffin * Unless required by applicable law or agreed to in writing, software distributed under the License
100888a09821a98ac0680fad765217302858e70fa4Paul Duffin * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
110888a09821a98ac0680fad765217302858e70fa4Paul Duffin * or implied. See the License for the specific language governing permissions and limitations under
120888a09821a98ac0680fad765217302858e70fa4Paul Duffin * the License.
130888a09821a98ac0680fad765217302858e70fa4Paul Duffin */
140888a09821a98ac0680fad765217302858e70fa4Paul Duffin
150888a09821a98ac0680fad765217302858e70fa4Paul Duffinpackage com.google.common.collect;
160888a09821a98ac0680fad765217302858e70fa4Paul Duffin
170888a09821a98ac0680fad765217302858e70fa4Paul Duffinimport static com.google.common.base.Preconditions.checkArgument;
180888a09821a98ac0680fad765217302858e70fa4Paul Duffin
190888a09821a98ac0680fad765217302858e70fa4Paul Duffinimport com.google.caliper.BeforeExperiment;
200888a09821a98ac0680fad765217302858e70fa4Paul Duffinimport com.google.caliper.Benchmark;
210888a09821a98ac0680fad765217302858e70fa4Paul Duffinimport com.google.caliper.Param;
220888a09821a98ac0680fad765217302858e70fa4Paul Duffin
230888a09821a98ac0680fad765217302858e70fa4Paul Duffinimport java.util.ArrayList;
240888a09821a98ac0680fad765217302858e70fa4Paul Duffinimport java.util.Collections;
250888a09821a98ac0680fad765217302858e70fa4Paul Duffinimport java.util.LinkedHashSet;
260888a09821a98ac0680fad765217302858e70fa4Paul Duffinimport java.util.List;
270888a09821a98ac0680fad765217302858e70fa4Paul Duffinimport java.util.Random;
280888a09821a98ac0680fad765217302858e70fa4Paul Duffinimport java.util.Set;
290888a09821a98ac0680fad765217302858e70fa4Paul Duffinimport java.util.TreeSet;
300888a09821a98ac0680fad765217302858e70fa4Paul Duffin
310888a09821a98ac0680fad765217302858e70fa4Paul Duffin/**
320888a09821a98ac0680fad765217302858e70fa4Paul Duffin * Provides supporting data for performance notes in the documentation of {@link
330888a09821a98ac0680fad765217302858e70fa4Paul Duffin * Ordering#sortedCopy} and {@link Ordering#immutableSortedCopy}, as well as for
340888a09821a98ac0680fad765217302858e70fa4Paul Duffin * automated code suggestions.
350888a09821a98ac0680fad765217302858e70fa4Paul Duffin *
360888a09821a98ac0680fad765217302858e70fa4Paul Duffin */
370888a09821a98ac0680fad765217302858e70fa4Paul Duffinpublic class SortedCopyBenchmark {
380888a09821a98ac0680fad765217302858e70fa4Paul Duffin  @Param({"1", "10", "1000", "1000000"}) int size; // logarithmic triangular
390888a09821a98ac0680fad765217302858e70fa4Paul Duffin
400888a09821a98ac0680fad765217302858e70fa4Paul Duffin  @Param boolean mutable;
410888a09821a98ac0680fad765217302858e70fa4Paul Duffin
420888a09821a98ac0680fad765217302858e70fa4Paul Duffin  @Param InputOrder inputOrder;
430888a09821a98ac0680fad765217302858e70fa4Paul Duffin
440888a09821a98ac0680fad765217302858e70fa4Paul Duffin  enum InputOrder {
450888a09821a98ac0680fad765217302858e70fa4Paul Duffin    SORTED {
460888a09821a98ac0680fad765217302858e70fa4Paul Duffin      @Override void arrange(List<Integer> list) {
470888a09821a98ac0680fad765217302858e70fa4Paul Duffin        Collections.sort(list);
480888a09821a98ac0680fad765217302858e70fa4Paul Duffin      }
490888a09821a98ac0680fad765217302858e70fa4Paul Duffin    },
500888a09821a98ac0680fad765217302858e70fa4Paul Duffin    ALMOST_SORTED {
510888a09821a98ac0680fad765217302858e70fa4Paul Duffin      @Override void arrange(List<Integer> list) {
520888a09821a98ac0680fad765217302858e70fa4Paul Duffin        Collections.sort(list);
530888a09821a98ac0680fad765217302858e70fa4Paul Duffin        if (list.size() > 1) {
540888a09821a98ac0680fad765217302858e70fa4Paul Duffin          int i = (list.size() - 1) / 2;
550888a09821a98ac0680fad765217302858e70fa4Paul Duffin          Collections.swap(list, i, i + 1);
560888a09821a98ac0680fad765217302858e70fa4Paul Duffin        }
570888a09821a98ac0680fad765217302858e70fa4Paul Duffin      }
580888a09821a98ac0680fad765217302858e70fa4Paul Duffin    },
590888a09821a98ac0680fad765217302858e70fa4Paul Duffin    RANDOM {
600888a09821a98ac0680fad765217302858e70fa4Paul Duffin      @Override void arrange(List<Integer> list) {}
610888a09821a98ac0680fad765217302858e70fa4Paul Duffin    };
620888a09821a98ac0680fad765217302858e70fa4Paul Duffin
630888a09821a98ac0680fad765217302858e70fa4Paul Duffin    abstract void arrange(List<Integer> list);
640888a09821a98ac0680fad765217302858e70fa4Paul Duffin  }
650888a09821a98ac0680fad765217302858e70fa4Paul Duffin
660888a09821a98ac0680fad765217302858e70fa4Paul Duffin  private ImmutableList<Integer> input;
670888a09821a98ac0680fad765217302858e70fa4Paul Duffin
680888a09821a98ac0680fad765217302858e70fa4Paul Duffin  @BeforeExperiment
690888a09821a98ac0680fad765217302858e70fa4Paul Duffin  void setUp() {
700888a09821a98ac0680fad765217302858e70fa4Paul Duffin    checkArgument(size > 0, "empty collection not supported");
710888a09821a98ac0680fad765217302858e70fa4Paul Duffin    Set<Integer> set = new LinkedHashSet<Integer>(size);
720888a09821a98ac0680fad765217302858e70fa4Paul Duffin
730888a09821a98ac0680fad765217302858e70fa4Paul Duffin    Random random = new Random();
740888a09821a98ac0680fad765217302858e70fa4Paul Duffin    while (set.size() < size) {
750888a09821a98ac0680fad765217302858e70fa4Paul Duffin      set.add(random.nextInt());
760888a09821a98ac0680fad765217302858e70fa4Paul Duffin    }
770888a09821a98ac0680fad765217302858e70fa4Paul Duffin    List<Integer> list = new ArrayList<Integer>(set);
780888a09821a98ac0680fad765217302858e70fa4Paul Duffin    inputOrder.arrange(list);
790888a09821a98ac0680fad765217302858e70fa4Paul Duffin    input = ImmutableList.copyOf(list);
800888a09821a98ac0680fad765217302858e70fa4Paul Duffin  }
810888a09821a98ac0680fad765217302858e70fa4Paul Duffin
820888a09821a98ac0680fad765217302858e70fa4Paul Duffin  @Benchmark
830888a09821a98ac0680fad765217302858e70fa4Paul Duffin  int collections(int reps) {
840888a09821a98ac0680fad765217302858e70fa4Paul Duffin    int dummy = 0;
850888a09821a98ac0680fad765217302858e70fa4Paul Duffin    // Yes, this could be done more elegantly
860888a09821a98ac0680fad765217302858e70fa4Paul Duffin    if (mutable) {
870888a09821a98ac0680fad765217302858e70fa4Paul Duffin      for (int i = 0; i < reps; i++) {
880888a09821a98ac0680fad765217302858e70fa4Paul Duffin        List<Integer> copy = new ArrayList<Integer>(input);
890888a09821a98ac0680fad765217302858e70fa4Paul Duffin        Collections.sort(copy);
900888a09821a98ac0680fad765217302858e70fa4Paul Duffin        dummy += copy.get(0);
910888a09821a98ac0680fad765217302858e70fa4Paul Duffin      }
920888a09821a98ac0680fad765217302858e70fa4Paul Duffin    } else {
930888a09821a98ac0680fad765217302858e70fa4Paul Duffin      for (int i = 0; i < reps; i++) {
940888a09821a98ac0680fad765217302858e70fa4Paul Duffin        List<Integer> copy = new ArrayList<Integer>(input);
950888a09821a98ac0680fad765217302858e70fa4Paul Duffin        Collections.sort(copy);
960888a09821a98ac0680fad765217302858e70fa4Paul Duffin        dummy += ImmutableList.copyOf(copy).get(0);
970888a09821a98ac0680fad765217302858e70fa4Paul Duffin      }
980888a09821a98ac0680fad765217302858e70fa4Paul Duffin    }
990888a09821a98ac0680fad765217302858e70fa4Paul Duffin    return dummy;
1000888a09821a98ac0680fad765217302858e70fa4Paul Duffin  }
1010888a09821a98ac0680fad765217302858e70fa4Paul Duffin
1020888a09821a98ac0680fad765217302858e70fa4Paul Duffin  @Benchmark
1030888a09821a98ac0680fad765217302858e70fa4Paul Duffin  int ordering(int reps) {
1040888a09821a98ac0680fad765217302858e70fa4Paul Duffin    int dummy = 0;
1050888a09821a98ac0680fad765217302858e70fa4Paul Duffin    if (mutable) {
1060888a09821a98ac0680fad765217302858e70fa4Paul Duffin      for (int i = 0; i < reps; i++) {
1070888a09821a98ac0680fad765217302858e70fa4Paul Duffin        dummy += ORDERING.sortedCopy(input).get(0);
1080888a09821a98ac0680fad765217302858e70fa4Paul Duffin      }
1090888a09821a98ac0680fad765217302858e70fa4Paul Duffin    } else {
1100888a09821a98ac0680fad765217302858e70fa4Paul Duffin      for (int i = 0; i < reps; i++) {
1110888a09821a98ac0680fad765217302858e70fa4Paul Duffin        dummy += ORDERING.immutableSortedCopy(input).get(0);
1120888a09821a98ac0680fad765217302858e70fa4Paul Duffin      }
1130888a09821a98ac0680fad765217302858e70fa4Paul Duffin    }
1140888a09821a98ac0680fad765217302858e70fa4Paul Duffin    return dummy;
1150888a09821a98ac0680fad765217302858e70fa4Paul Duffin  }
1160888a09821a98ac0680fad765217302858e70fa4Paul Duffin
1170888a09821a98ac0680fad765217302858e70fa4Paul Duffin  @Benchmark
1180888a09821a98ac0680fad765217302858e70fa4Paul Duffin  int sortedSet(int reps) {
1190888a09821a98ac0680fad765217302858e70fa4Paul Duffin    int dummy = 0;
1200888a09821a98ac0680fad765217302858e70fa4Paul Duffin    if (mutable) {
1210888a09821a98ac0680fad765217302858e70fa4Paul Duffin      for (int i = 0; i < reps; i++) {
1220888a09821a98ac0680fad765217302858e70fa4Paul Duffin        dummy += new TreeSet<Integer>(input).first();
1230888a09821a98ac0680fad765217302858e70fa4Paul Duffin      }
1240888a09821a98ac0680fad765217302858e70fa4Paul Duffin    } else {
1250888a09821a98ac0680fad765217302858e70fa4Paul Duffin      for (int i = 0; i < reps; i++) {
1260888a09821a98ac0680fad765217302858e70fa4Paul Duffin        dummy += ImmutableSortedSet.copyOf(input).first();
1270888a09821a98ac0680fad765217302858e70fa4Paul Duffin      }
1280888a09821a98ac0680fad765217302858e70fa4Paul Duffin    }
1290888a09821a98ac0680fad765217302858e70fa4Paul Duffin    return dummy;
1300888a09821a98ac0680fad765217302858e70fa4Paul Duffin  }
1310888a09821a98ac0680fad765217302858e70fa4Paul Duffin
1320888a09821a98ac0680fad765217302858e70fa4Paul Duffin  private static final Ordering<Integer> ORDERING = Ordering.natural();
1330888a09821a98ac0680fad765217302858e70fa4Paul Duffin}
134