| /* |
| * Copyright (C) 2013 The Guava Authors |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| |
| package com.google.common.base; |
| |
| import static com.google.common.base.Throwables.lazyStackTrace; |
| import static java.util.Arrays.asList; |
| |
| import com.google.caliper.BeforeExperiment; |
| import com.google.caliper.Benchmark; |
| import com.google.caliper.Param; |
| import com.google.caliper.api.SkipThisScenarioException; |
| import java.util.List; |
| |
| /** |
| * Quick and dirty benchmark of {@link Throwables#lazyStackTrace(Throwable)}. We benchmark a "caller |
| * finder" implementation that might be used in a logging framework. |
| */ |
| public class LazyStackTraceBenchmark { |
| @Param({"20", "200", "2000"}) |
| int stackDepth; |
| |
| @Param({"-1", "3", "15"}) |
| int breakAt; |
| |
| int recursionCount; |
| |
| private static final Object duh = new Object(); |
| |
| @Param Mode mode; |
| |
| enum Mode { |
| LAZY_STACK_TRACE { |
| @Override |
| List<StackTraceElement> getStackTrace(Throwable t) { |
| return lazyStackTrace(t); |
| } |
| }, |
| GET_STACK_TRACE { |
| @Override |
| List<StackTraceElement> getStackTrace(Throwable t) { |
| return asList(t.getStackTrace()); |
| } |
| }; |
| |
| boolean timeIt(int reps, int breakAt) { |
| boolean dummy = false; |
| for (int i = 0; i < reps; i++) { |
| int f = 0; |
| Throwable t = new Throwable(); |
| for (StackTraceElement ste : getStackTrace(t)) { |
| dummy |= ste == duh; |
| if (f++ == breakAt) { |
| break; |
| } |
| } |
| } |
| return dummy; |
| } |
| |
| abstract List<StackTraceElement> getStackTrace(Throwable t); |
| } |
| |
| @BeforeExperiment |
| public void doBefore() { |
| recursionCount = stackDepth - new Throwable().getStackTrace().length - 1; |
| if (recursionCount < 0) { |
| throw new SkipThisScenarioException(); |
| } |
| } |
| |
| @Benchmark |
| public boolean timeFindCaller(int reps) { |
| return timeFindCaller(reps, recursionCount); |
| } |
| |
| private boolean timeFindCaller(int reps, int recurse) { |
| return recurse > 0 ? timeFindCaller(reps, recurse - 1) : mode.timeIt(reps, breakAt); |
| } |
| } |