111 }
112
113 @Benchmark
114 public int sixValues_ThreadLocal() throws Exception {
115 int result = 0;
116 for (int i = 0 ; i < 166; i++) {
117 result = combine(result, tl1.get(), tl2.get(), tl3.get(), tl4.get(), tl5.get(), tl6.get());
118 }
119 return result;
120 }
121
122 // Test 3: The cost of bind, then get
123 // This is the worst case for ScopedValues because we have to create
124 // a binding, link it in, then search the current bindings. In addition, we
125 // create a cache entry for the bound value, then we immediately have to
126 // destroy it.
127
128 @Benchmark
129 @OutputTimeUnit(TimeUnit.NANOSECONDS)
130 public int CreateBindThenGetThenRemove_ScopedValue() throws Exception {
131 return ScopedValue.where(sl1, THE_ANSWER).call(sl1::get);
132 }
133
134
135 // Create a Carrier ahead of time: might be slightly faster
136 private static final ScopedValue.Carrier HOLD_42 = ScopedValue.where(sl1, 42);
137 @Benchmark
138 @OutputTimeUnit(TimeUnit.NANOSECONDS)
139 public int bindThenGetThenRemove_ScopedValue() throws Exception {
140 return HOLD_42.call(sl1::get);
141 }
142
143 @Benchmark
144 @OutputTimeUnit(TimeUnit.NANOSECONDS)
145 public int bindThenGetThenRemove_ThreadLocal() throws Exception {
146 try {
147 tl1.set(THE_ANSWER);
148 return tl1.get();
149 } finally {
150 tl1.remove();
151 }
152 }
153
154 // This has no exact equivalent in ScopedValue, but it's provided here for
155 // information.
156 @Benchmark
157 @OutputTimeUnit(TimeUnit.NANOSECONDS)
158 public int bindThenGetNoRemove_ThreadLocal() throws Exception {
159 tl1.set(THE_ANSWER);
160 return tl1.get();
161 }
162
163 // Test 4: The cost of binding, but not using any result
164 @Benchmark
165 @OutputTimeUnit(TimeUnit.NANOSECONDS)
166 public Object bind_ScopedValue() throws Exception {
167 return HOLD_42.call(aCallable);
168 }
169 private static final Callable<Class<?>> aCallable = () -> ScopedValues.class;
170
171 // Same, but make sure that Carrier.get(Supplier) is no slower
172 // than Carrier.call(Callable).
173 @Benchmark
174 @OutputTimeUnit(TimeUnit.NANOSECONDS)
175 public Object bindViaGet_ScopedValue() {
176 return HOLD_42.get(aSupplier);
177 }
178 private static final Supplier<Class<?>> aSupplier = () -> ScopedValues.class;
179
180 @Benchmark
181 @OutputTimeUnit(TimeUnit.NANOSECONDS)
182 public Object bind_ThreadLocal() throws Exception {
183 try {
184 tl1.set(THE_ANSWER);
185 return this.getClass();
186 } finally {
187 tl1.remove();
188 }
189 }
190
191 // Simply set a ThreadLocal so that the caller can see it
192 // This has no exact equivalent in ScopedValue, but it's provided here for
193 // information.
194 @Benchmark
195 @OutputTimeUnit(TimeUnit.NANOSECONDS)
196 public void setNoRemove_ThreadLocal() throws Exception {
|
111 }
112
113 @Benchmark
114 public int sixValues_ThreadLocal() throws Exception {
115 int result = 0;
116 for (int i = 0 ; i < 166; i++) {
117 result = combine(result, tl1.get(), tl2.get(), tl3.get(), tl4.get(), tl5.get(), tl6.get());
118 }
119 return result;
120 }
121
122 // Test 3: The cost of bind, then get
123 // This is the worst case for ScopedValues because we have to create
124 // a binding, link it in, then search the current bindings. In addition, we
125 // create a cache entry for the bound value, then we immediately have to
126 // destroy it.
127
128 @Benchmark
129 @OutputTimeUnit(TimeUnit.NANOSECONDS)
130 public int CreateBindThenGetThenRemove_ScopedValue() throws Exception {
131 return ScopedValue.callWhere(sl1, THE_ANSWER, sl1::get);
132 }
133
134
135 // Create a Carrier ahead of time: might be slightly faster
136 private static final ScopedValue.Carrier HOLD_42 = ScopedValue.where(sl1, 42);
137 @Benchmark
138 @OutputTimeUnit(TimeUnit.NANOSECONDS)
139 public int bindThenGetThenRemove_ScopedValue() throws Exception {
140 return ScopedValue.callWhere(HOLD_42, sl1::get);
141 }
142
143 @Benchmark
144 @OutputTimeUnit(TimeUnit.NANOSECONDS)
145 public int bindThenGetThenRemove_ThreadLocal() throws Exception {
146 try {
147 tl1.set(THE_ANSWER);
148 return tl1.get();
149 } finally {
150 tl1.remove();
151 }
152 }
153
154 // This has no exact equivalent in ScopedValue, but it's provided here for
155 // information.
156 @Benchmark
157 @OutputTimeUnit(TimeUnit.NANOSECONDS)
158 public int bindThenGetNoRemove_ThreadLocal() throws Exception {
159 tl1.set(THE_ANSWER);
160 return tl1.get();
161 }
162
163 // Test 4: The cost of binding, but not using any result
164 @Benchmark
165 @OutputTimeUnit(TimeUnit.NANOSECONDS)
166 public Object bind_ScopedValue() throws Exception {
167 return ScopedValue.callWhere(HOLD_42, aCallable);
168 }
169 private static final Callable<Class<?>> aCallable = () -> ScopedValues.class;
170
171 // Same, but make sure that Carrier.get(Supplier) is no slower
172 // than Carrier.call(Callable).
173 @Benchmark
174 @OutputTimeUnit(TimeUnit.NANOSECONDS)
175 public Object bindViaGet_ScopedValue() {
176 return ScopedValue.getWhere(HOLD_42, aSupplier);
177 }
178 private static final Supplier<Class<?>> aSupplier = () -> ScopedValues.class;
179
180 @Benchmark
181 @OutputTimeUnit(TimeUnit.NANOSECONDS)
182 public Object bind_ThreadLocal() throws Exception {
183 try {
184 tl1.set(THE_ANSWER);
185 return this.getClass();
186 } finally {
187 tl1.remove();
188 }
189 }
190
191 // Simply set a ThreadLocal so that the caller can see it
192 // This has no exact equivalent in ScopedValue, but it's provided here for
193 // information.
194 @Benchmark
195 @OutputTimeUnit(TimeUnit.NANOSECONDS)
196 public void setNoRemove_ThreadLocal() throws Exception {
|