package org.gridkit.jvmtool.stacktrace; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.util.ArrayList; import java.util.List; import java.util.regex.Matcher; import java.util.regex.Pattern; import org.junit.Ignore; import org.junit.Rule; import org.junit.Test; import org.junit.rules.TestName; import com.carrotsearch.junitbenchmarks.BenchmarkRule; @Ignore("Benchmark") public class RegExMicrobenchmark { private static StackFrame[] FRAMES; private static StackFrame[] INTERNED_FRAMES; private static StackTraceElement[] TRACE_ELEMENTS; static { FRAMES = loadFrames("stack-frame.txt", 1000); INTERNED_FRAMES = new StackFrame[FRAMES.length]; TRACE_ELEMENTS = new StackTraceElement[FRAMES.length]; for(int i = 0; i != FRAMES.length; ++i) { INTERNED_FRAMES[i] = FRAMES[i].internSymbols(); TRACE_ELEMENTS[i] = FRAMES[i].toStackTraceElement(); } } private static Pattern pattern1 = GlobHelper.translate("org.hibernate.type.AbstractStandardBasicType.getHashCode", "."); private static Pattern pattern2 = GlobHelper.translate("**.TagMethodExpression.invoke", "."); private static Pattern pattern3 = GlobHelper.translate("org.jboss.seam.**", "."); private static StackFrame[] loadFrames(String res, int multiplier) { try { List<StackFrame> frames = new ArrayList<StackFrame>(); for(int i = 0; i != multiplier; ++i) { InputStream is = Thread.currentThread().getContextClassLoader().getResourceAsStream(res); BufferedReader br = new BufferedReader(new InputStreamReader(is)); while(true) { String line = br.readLine(); if (line == null) { break; } if (line.trim().length() > 0) frames.add(StackFrame.parseFrame(line.trim())); } } return frames.toArray(new StackFrame[frames.size()]); } catch (IOException e) { throw new RuntimeException(e); } }; @Rule public TestName testName = new TestName(); @Rule public volatile BenchmarkRule benchmark = new BenchmarkRule(); @Test public void frame_pattern1() { testFrameMatcher(FRAMES, pattern1); } @Test public void frame_pattern2() { testFrameMatcher(FRAMES, pattern2); } @Test public void frame_pattern3() { testFrameMatcher(FRAMES, pattern3); } @Test public void frame_patternAll() { testFrameMatcher(FRAMES, pattern1, pattern2, pattern3); } @Test public void interned_frame_pattern1() { testFrameMatcher(INTERNED_FRAMES, pattern1); } @Test public void interned_frame_pattern2() { testFrameMatcher(INTERNED_FRAMES, pattern2); } @Test public void interned_frame_pattern3() { testFrameMatcher(INTERNED_FRAMES, pattern3); } @Test public void interned_frame_patternAll() { testFrameMatcher(INTERNED_FRAMES, pattern1, pattern2, pattern3); } @Test public void trace_element_pattern1() { testFrameMatcher(TRACE_ELEMENTS, pattern1); } @Test public void trace_element_pattern2() { testFrameMatcher(TRACE_ELEMENTS, pattern2); } @Test public void trace_element_pattern3() { testFrameMatcher(TRACE_ELEMENTS, pattern3); } @Test public void trace_element_patternAll() { testFrameMatcher(TRACE_ELEMENTS, pattern1, pattern2, pattern3); } protected void testFrameMatcher(StackFrame[] frames, Pattern... pattern) { int[] count = new int[pattern.length]; Matcher[] matcher = new Matcher[pattern.length]; for(int i = 0; i != pattern.length; ++i) { matcher[i] = pattern[i].matcher(""); } for(StackFrame frame: frames) { for(int i = 0; i != pattern.length; ++i) { if (match(frame, matcher[i])) { ++count[i]; } } } if (benchmark == null) { System.out.println(testName.getMethodName()); for(int i = 0; i != pattern.length; ++i) { System.out.println(" " + count[i] + " - " + pattern[i].pattern()); } } } protected void testFrameMatcher(StackTraceElement[] frames, Pattern... pattern) { int[] count = new int[pattern.length]; Matcher[] matcher = new Matcher[pattern.length]; for(int i = 0; i != pattern.length; ++i) { matcher[i] = pattern[i].matcher(""); } for(StackTraceElement frame: frames) { for(int i = 0; i != pattern.length; ++i) { if (match(frame.toString(), matcher[i])) { ++count[i]; } } } if (benchmark == null) { System.out.println(testName.getMethodName()); for(int i = 0; i != pattern.length; ++i) { System.out.println(" " + count[i] + " - " + pattern[i].pattern()); } } } private boolean match(CharSequence frame, Matcher pattern) { pattern.reset(frame); return pattern.lookingAt(); } }