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