Skip to content

Instantly share code, notes, and snippets.

@raphw
Created October 20, 2017 13:15
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save raphw/96e7c81d7c719cf7991b361bb7266c70 to your computer and use it in GitHub Desktop.
Save raphw/96e7c81d7c719cf7991b361bb7266c70 to your computer and use it in GitHub Desktop.
Approaches to stack extraction.
import org.openjdk.jmh.annotations.Benchmark;
public class StackWalkerExtraction {
private static Object call(int depth, Callable<?> result) throws Exception {
if (depth == 0) {
return result.call();
} else {
return call(depth - 1, result);
}
}
@Benchmark
public Object snapshot() throws Exception {
return call(100, () -> StackWalker.getInstance().walk(new InstanaWalker(35, 0)));
}
@Benchmark
public Object complete() throws Exception {
return call(100, () -> StackWalker.getInstance().walk(new InstanaWalker(35, 0)));
}
private class RawWalker implements Function<Stream<StackWalker.StackFrame>, StackWalker.StackFrame[]> {
private final int stackDepth, startFrame;
RawWalker(int stackDepth, int startFrame) {
this.stackDepth = stackDepth;
this.startFrame = startFrame;
}
@Override
public StackWalker.StackFrame[] apply(Stream<StackWalker.StackFrame> stackFrameStream) {
StackWalker.StackFrame[] elements = new StackWalker.StackFrame[stackDepth];
Iterator<StackWalker.StackFrame> it = stackFrameStream.skip(startFrame).limit(stackDepth).iterator();
int index = 0;
while (it.hasNext()) {
elements[index++] = it.next();
}
return elements;
}
}
private class TransformingWalker implements Function<Stream<StackWalker.StackFrame>, StackWalker.StackFrame[]> {
private final int stackDepth, startFrame;
TransformingWalker(int stackDepth, int startFrame) {
this.stackDepth = stackDepth;
this.startFrame = startFrame;
}
@Override
public StackFrameElement[] apply(Stream<StackWalker.StackFrame> stackFrameStream) {
StackFrameElement[] elements = new StackWalker.StackFrame[stackDepth];
Iterator<StackWalker.StackFrame> it = stackFrameStream.skip(startFrame).limit(stackDepth).iterator();
int index = 0;
while (it.hasNext()) {
elements[index++] = it.next().toStackFrameElement();
}
return elements;
}
}
}
import org.openjdk.jmh.annotations.Benchmark;
public class ThrowableExtraction {
private static Throwable call(int depth) {
if (depth == 0) {
return new Throwable();
} else {
return call(depth - 1);
}
}
@Benchmark
public Throwable snapshot() {
return call(100);
}
@Benchmark
public Object complete() {
int stackDepth = 35, startFrame = 1;
Throwable throwable = call(100);
StackTraceElement[] source = throwable.getStackTrace();
StackTraceElement[] copy = new StackTraceElement[Math.min(stackDepth, source.length - startFrame)];
int sourceIndex = startFrame;
int copyIndex = 0;
while (sourceIndex < source.length && copyIndex < copy.length) {
copy[copyIndex++] = source[sourceIndex++];
}
return copy;
}
}
import org.openjdk.jmh.annotations.Benchmark;
public class ThrowableSecretExtraction {
static final JavaLangAccess JAVA_LANG_ACCESS = SharedSecrets.getJavaLangAccess();
private static Throwable call(int depth) {
if (depth == 0) {
return new Throwable();
} else {
return call(depth - 1);
}
}
@Benchmark
public Throwable snapshot() {
return call(100);
}
@Benchmark
public Object complete() {
int stackDepth = 35, startFrame = 1;
Throwable throwable = call(100);
int length = JAVA_LANG_ACCESS.getStackTraceDepth(throwable);
StackTraceElement[] copy = new StackTraceElement[Math.min(stackDepth, source.length - startFrame)];
int sourceIndex = startFrame;
int copyIndex = 0;
while (sourceIndex < length && copyIndex < copy.length) {
copy[copyIndex++] = JAVA_LANG_ACCESS.getStackTraceElement(throwable, sorceIndex++);
}
return copy;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment