Home | History | Annotate | Download | only in math
      1 /*
      2  * Copyright (C) 2013 The Guava Authors
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  * http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 package com.google.common.math;
     18 
     19 import com.google.caliper.BeforeExperiment;
     20 import com.google.caliper.Benchmark;
     21 import com.google.caliper.Param;
     22 
     23 import java.util.Random;
     24 
     25 /**
     26  * Benchmarks for various ways of writing the expression {@code foo + ((bar < baz) ? 1 : 0)}.
     27  *
     28  * @author Louis Wasserman
     29  */
     30 public class LessThanBenchmark {
     31   static final int SAMPLE_SIZE = 0x1000;
     32   static final int SAMPLE_MASK = 0x0FFF;
     33 
     34   @Param("1234")
     35   int randomSeed;
     36 
     37   int[] xInts;
     38   int[] yInts;
     39 
     40   long[] xLongs;
     41   long[] yLongs;
     42 
     43   int[] constant;
     44 
     45   private static final long NONNEGATIVE_LONG_MASK = 0x7FFFFFFFFFFFFFFFL;
     46 
     47   @BeforeExperiment
     48   void setUp() {
     49     Random random = new Random(randomSeed);
     50     xInts = new int[SAMPLE_SIZE];
     51     yInts = new int[SAMPLE_SIZE];
     52     xLongs = new long[SAMPLE_SIZE];
     53     yLongs = new long[SAMPLE_SIZE];
     54     constant = new int[SAMPLE_SIZE];
     55     for (int i = 0; i < SAMPLE_SIZE; i++) {
     56       xInts[i] = random.nextInt(Integer.MAX_VALUE);
     57       yInts[i] = random.nextInt(Integer.MAX_VALUE);
     58       xLongs[i] = random.nextLong() & NONNEGATIVE_LONG_MASK;
     59       yLongs[i] = random.nextLong() & NONNEGATIVE_LONG_MASK;
     60       constant[i] = random.nextInt();
     61     }
     62   }
     63 
     64   @Benchmark int branchFreeLtIntInlined(int reps) {
     65     int tmp = 0;
     66     for (int i = 0; i < reps; i++) {
     67       int j = i & SAMPLE_MASK;
     68       int x = xInts[j];
     69       int y = yInts[j];
     70       int z = constant[j];
     71       tmp += z + ((x - y) >>> (Integer.SIZE - 1));
     72     }
     73     return tmp;
     74   }
     75 
     76   @Benchmark int branchFreeLtInt(int reps) {
     77     int tmp = 0;
     78     for (int i = 0; i < reps; i++) {
     79       int j = i & SAMPLE_MASK;
     80       int x = xInts[j];
     81       int y = yInts[j];
     82       int z = constant[j];
     83       tmp += z + IntMath.lessThanBranchFree(x, y);
     84     }
     85     return tmp;
     86   }
     87 
     88   @Benchmark int ternaryLtIntAddOutsideTernary(int reps) {
     89     int tmp = 0;
     90     for (int i = 0; i < reps; i++) {
     91       int j = i & SAMPLE_MASK;
     92       int x = xInts[j];
     93       int y = yInts[j];
     94       int z = constant[j];
     95       tmp += z + ((x < y) ? 1 : 0);
     96     }
     97     return tmp;
     98   }
     99 
    100   @Benchmark int ternaryLtIntAddInsideTernary(int reps) {
    101     int tmp = 0;
    102     for (int i = 0; i < reps; i++) {
    103       int j = i & SAMPLE_MASK;
    104       int x = xInts[j];
    105       int y = yInts[j];
    106       int z = constant[j];
    107       tmp += (x < y) ? z + 1 : z;
    108     }
    109     return tmp;
    110   }
    111 
    112   @Benchmark int branchFreeLtLongInlined(int reps) {
    113     int tmp = 0;
    114     for (int i = 0; i < reps; i++) {
    115       int j = i & SAMPLE_MASK;
    116       long x = xLongs[j];
    117       long y = yLongs[j];
    118       int z = constant[j];
    119       tmp += z + (int) ((x - y) >>> (Long.SIZE - 1));
    120     }
    121     return tmp;
    122   }
    123 
    124   @Benchmark int branchFreeLtLong(int reps) {
    125     int tmp = 0;
    126     for (int i = 0; i < reps; i++) {
    127       int j = i & SAMPLE_MASK;
    128       long x = xLongs[j];
    129       long y = yLongs[j];
    130       int z = constant[j];
    131       tmp += z + LongMath.lessThanBranchFree(x, y);
    132     }
    133     return tmp;
    134   }
    135 
    136   @Benchmark int ternaryLtLongAddOutsideTernary(int reps) {
    137     int tmp = 0;
    138     for (int i = 0; i < reps; i++) {
    139       int j = i & SAMPLE_MASK;
    140       long x = xLongs[j];
    141       long y = yLongs[j];
    142       int z = constant[j];
    143       tmp += z + ((x < y) ? 1 : 0);
    144     }
    145     return tmp;
    146   }
    147 
    148   @Benchmark int ternaryLtLongAddInsideTernary(int reps) {
    149     int tmp = 0;
    150     for (int i = 0; i < reps; i++) {
    151       int j = i & SAMPLE_MASK;
    152       long x = xLongs[j];
    153       long y = yLongs[j];
    154       int z = constant[j];
    155       tmp += (x < y) ? z + 1 : z;
    156     }
    157     return tmp;
    158   }
    159 }
    160