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 import java.util.Random; 23 24 /** 25 * Benchmarks for various ways of writing the expression {@code foo + ((bar < baz) ? 1 : 0)}. 26 * 27 * @author Louis Wasserman 28 */ 29 public class LessThanBenchmark { 30 static final int SAMPLE_SIZE = 0x1000; 31 static final int SAMPLE_MASK = 0x0FFF; 32 33 @Param("1234") 34 int randomSeed; 35 36 int[] xInts; 37 int[] yInts; 38 39 long[] xLongs; 40 long[] yLongs; 41 42 int[] constant; 43 44 private static final long NONNEGATIVE_LONG_MASK = 0x7FFFFFFFFFFFFFFFL; 45 46 @BeforeExperiment setUp()47 void setUp() { 48 Random random = new Random(randomSeed); 49 xInts = new int[SAMPLE_SIZE]; 50 yInts = new int[SAMPLE_SIZE]; 51 xLongs = new long[SAMPLE_SIZE]; 52 yLongs = new long[SAMPLE_SIZE]; 53 constant = new int[SAMPLE_SIZE]; 54 for (int i = 0; i < SAMPLE_SIZE; i++) { 55 xInts[i] = random.nextInt(Integer.MAX_VALUE); 56 yInts[i] = random.nextInt(Integer.MAX_VALUE); 57 xLongs[i] = random.nextLong() & NONNEGATIVE_LONG_MASK; 58 yLongs[i] = random.nextLong() & NONNEGATIVE_LONG_MASK; 59 constant[i] = random.nextInt(); 60 } 61 } 62 63 @Benchmark branchFreeLtIntInlined(int reps)64 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 branchFreeLtInt(int reps)77 int branchFreeLtInt(int reps) { 78 int tmp = 0; 79 for (int i = 0; i < reps; i++) { 80 int j = i & SAMPLE_MASK; 81 int x = xInts[j]; 82 int y = yInts[j]; 83 int z = constant[j]; 84 tmp += z + IntMath.lessThanBranchFree(x, y); 85 } 86 return tmp; 87 } 88 89 @Benchmark ternaryLtIntAddOutsideTernary(int reps)90 int ternaryLtIntAddOutsideTernary(int reps) { 91 int tmp = 0; 92 for (int i = 0; i < reps; i++) { 93 int j = i & SAMPLE_MASK; 94 int x = xInts[j]; 95 int y = yInts[j]; 96 int z = constant[j]; 97 tmp += z + ((x < y) ? 1 : 0); 98 } 99 return tmp; 100 } 101 102 @Benchmark ternaryLtIntAddInsideTernary(int reps)103 int ternaryLtIntAddInsideTernary(int reps) { 104 int tmp = 0; 105 for (int i = 0; i < reps; i++) { 106 int j = i & SAMPLE_MASK; 107 int x = xInts[j]; 108 int y = yInts[j]; 109 int z = constant[j]; 110 tmp += (x < y) ? z + 1 : z; 111 } 112 return tmp; 113 } 114 115 @Benchmark branchFreeLtLongInlined(int reps)116 int branchFreeLtLongInlined(int reps) { 117 int tmp = 0; 118 for (int i = 0; i < reps; i++) { 119 int j = i & SAMPLE_MASK; 120 long x = xLongs[j]; 121 long y = yLongs[j]; 122 int z = constant[j]; 123 tmp += z + (int) ((x - y) >>> (Long.SIZE - 1)); 124 } 125 return tmp; 126 } 127 128 @Benchmark branchFreeLtLong(int reps)129 int branchFreeLtLong(int reps) { 130 int tmp = 0; 131 for (int i = 0; i < reps; i++) { 132 int j = i & SAMPLE_MASK; 133 long x = xLongs[j]; 134 long y = yLongs[j]; 135 int z = constant[j]; 136 tmp += z + LongMath.lessThanBranchFree(x, y); 137 } 138 return tmp; 139 } 140 141 @Benchmark ternaryLtLongAddOutsideTernary(int reps)142 int ternaryLtLongAddOutsideTernary(int reps) { 143 int tmp = 0; 144 for (int i = 0; i < reps; i++) { 145 int j = i & SAMPLE_MASK; 146 long x = xLongs[j]; 147 long y = yLongs[j]; 148 int z = constant[j]; 149 tmp += z + ((x < y) ? 1 : 0); 150 } 151 return tmp; 152 } 153 154 @Benchmark ternaryLtLongAddInsideTernary(int reps)155 int ternaryLtLongAddInsideTernary(int reps) { 156 int tmp = 0; 157 for (int i = 0; i < reps; i++) { 158 int j = i & SAMPLE_MASK; 159 long x = xLongs[j]; 160 long y = yLongs[j]; 161 int z = constant[j]; 162 tmp += (x < y) ? z + 1 : z; 163 } 164 return tmp; 165 } 166 } 167