Skip to content

Commit 7d74c05

Browse files
committed
使用类似MySQL查询结果的表格输出性能数据
1 parent 6fe8409 commit 7d74c05

2 files changed

Lines changed: 285 additions & 11 deletions

File tree

src/cn/aofeng/demo/script/MultiScriptEngineCompare.java

Lines changed: 160 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,14 @@
11
package cn.aofeng.demo.script;
22

3+
import java.util.ArrayList;
34
import java.util.HashMap;
5+
import java.util.Iterator;
6+
import java.util.List;
47
import java.util.Map;
58

69
import javax.script.Bindings;
10+
import javax.script.Compilable;
11+
import javax.script.CompiledScript;
712
import javax.script.ScriptEngine;
813
import javax.script.ScriptEngineManager;
914
import javax.script.ScriptException;
@@ -15,31 +20,45 @@
1520
*/
1621
public class MultiScriptEngineCompare {
1722

23+
public final static String PARSE = "parse";
24+
public final static String COMPILE = "compile";
25+
1826
/**
19-
* 获取指定的脚本引擎执行指定的脚本。
27+
* 获取指定的脚本引擎执行指定的脚本(解释执行)
2028
*
2129
* @param scriptEngineName 脚本引擎名称
2230
* @param script 脚本
2331
* @param count 脚本的执行次数
2432
* @param vars 绑定到脚本的变量集合
2533
* @throws ScriptException 执行脚本出错
2634
*/
27-
public void execute(String scriptEngineName, String script, int count,
35+
public ExecuteResult parse(String scriptEngineName, String script, int count,
2836
Map<String, Object> vars) throws ScriptException {
2937
ScriptEngine scriptEngine = getScriptEngine(scriptEngineName);
30-
System.out.println( String.format("脚本引擎:%s", scriptEngine.getFactory().getEngineName()) );
31-
System.out.println( String.format("脚本:%s", script) );
32-
System.out.println( String.format("脚本绑定参数:%s", vars) );
38+
// log("脚本引擎:%s", );
39+
// log("脚本:%s", script);
40+
// log("脚本绑定参数:%s", vars);
3341
long startTime = System.currentTimeMillis();
3442
for (int i = 0; i < count; i++) {
3543
runSingleScript(script, vars, scriptEngine);
3644
}
3745
long usedTime = System.currentTimeMillis() - startTime;
38-
System.out.println( String.format("脚本执行%d次,消耗%d毫秒。", count, usedTime) );
39-
System.out.println("");
46+
// log("解释执行脚本%d次,消耗%d毫秒。", count, usedTime);
47+
// log("");
48+
49+
ExecuteResult result = new ExecuteResult();
50+
result.setEngine(scriptEngine.getFactory().getEngineName());
51+
result.setScript(script);
52+
result.setBindParam(vars.toString());
53+
result.setExecuteCount(count);
54+
result.setExecuteType(PARSE);
55+
result.setUsedTime(usedTime);
56+
57+
return result;
4058
}
4159

42-
private void runSingleScript(String script, Map<String, Object> vars, ScriptEngine scriptEngine) throws ScriptException {
60+
private void runSingleScript(String script, Map<String, Object> vars,
61+
ScriptEngine scriptEngine) throws ScriptException {
4362
if (null == vars || vars.isEmpty()) {
4463
scriptEngine.eval(script);
4564
} else {
@@ -48,6 +67,51 @@ private void runSingleScript(String script, Map<String, Object> vars, ScriptEngi
4867
}
4968
}
5069

70+
public ExecuteResult compile(String scriptEngineName, String script, int count,
71+
Map<String, Object> vars) throws ScriptException {
72+
ScriptEngine scriptEngine = getScriptEngine(scriptEngineName);
73+
// log("脚本引擎:%s", scriptEngine.getFactory().getEngineName());
74+
// log("脚本:%s", script);
75+
// log("脚本绑定参数:%s", vars);
76+
Compilable compileEngine = (Compilable) scriptEngine;
77+
CompiledScript compileScript = compileEngine.compile(script);
78+
long startTime = System.currentTimeMillis();
79+
for (int i = 0; i < count; i++) {
80+
runSingleScript(compileScript, vars, scriptEngine);
81+
}
82+
long usedTime = System.currentTimeMillis() - startTime;
83+
// log("预编译脚本后执行%d次消耗%d毫秒", count, usedTime);
84+
// log("");
85+
86+
ExecuteResult result = new ExecuteResult();
87+
result.setEngine(scriptEngine.getFactory().getEngineName());
88+
result.setScript(script);
89+
result.setBindParam(vars.toString());
90+
result.setExecuteCount(count);
91+
result.setExecuteType(COMPILE);
92+
result.setUsedTime(usedTime);
93+
94+
return result;
95+
}
96+
97+
private void runSingleScript(CompiledScript compileScript, Map<String, Object> vars,
98+
ScriptEngine scriptEngine) throws ScriptException {
99+
if (null == vars || vars.isEmpty()) {
100+
compileScript.eval();
101+
} else {
102+
Bindings binds = createBinding(scriptEngine, vars);
103+
compileScript.eval(binds);
104+
}
105+
}
106+
107+
protected void log(String msg) {
108+
System.out.println(msg);
109+
}
110+
111+
protected void log(String msg, Object... args) {
112+
log( String.format(msg, args) );
113+
}
114+
51115
/**
52116
* 根据名称获取脚本引擎。
53117
*
@@ -74,11 +138,12 @@ private Bindings createBinding(ScriptEngine scriptEngine, Map<String, Object> va
74138
*/
75139
@SuppressWarnings({ "rawtypes", "unchecked" })
76140
public static void main(String[] args) throws ScriptException {
77-
if ( args.length != 1) {
78-
System.err.println("参数错误。使用示例\n java cn.aofeng.demo.script.MultiScriptEngineCompare 100000");
141+
if ( args.length != 2) {
142+
System.err.println("参数错误。\n语法格式\n java cn.aofeng.demo.script.MultiScriptEngineCompare 脚本执行次数 脚本执行方式(parse|compile)\n使用示例:\n java cn.aofeng.demo.script.MultiScriptEngineCompare 100000 parse");
79143
System.exit(-1);
80144
}
81145
int count = Integer.parseInt(args[0]);
146+
String executeType = args[1];
82147

83148
String[] scriptEngineList = {"JavaScript", "JEXL"};
84149

@@ -101,11 +166,95 @@ public static void main(String[] args) throws ScriptException {
101166
Map[] varsList = {vars1, vars2};
102167

103168
MultiScriptEngineCompare msec = new MultiScriptEngineCompare();
169+
List<MultiScriptEngineCompare.ExecuteResult> resultList = new ArrayList<MultiScriptEngineCompare.ExecuteResult>();
104170
for (int i = 0; i < scriptEngineList.length; i++) {
105171
for (int j = 0; j < scriptList.length; j++) {
106-
msec.execute(scriptEngineList[i], scriptList[j], count, varsList[j]);
172+
if (PARSE.equalsIgnoreCase(executeType)) {
173+
resultList.add( msec.parse(scriptEngineList[i], scriptList[j], count, varsList[j]) );
174+
} else if (COMPILE.equalsIgnoreCase(executeType)) {
175+
resultList.add( msec.compile(scriptEngineList[i], scriptList[j], count, varsList[j]) );
176+
} else {
177+
msec.log("错误的执行方式:%s", executeType);
178+
}
107179
}
108180
}
181+
182+
List<String[]> arrayList = new ArrayList<String[]>();
183+
arrayList.add(new String[]{"脚本引擎", "脚本", "脚本绑定参数", "脚本执行次数", "脚本执行类型", "消耗时间(毫秒)", "JDK版本"});
184+
for (Iterator iterator = resultList.iterator(); iterator.hasNext();) {
185+
ExecuteResult er = (ExecuteResult) iterator.next();
186+
arrayList.add(new String[]{er.getEngine(),
187+
er.getScript(),
188+
er.getBindParam(),
189+
String.valueOf(er.getExecuteCount()),
190+
er.getExecuteType(),
191+
String.valueOf(er.getUsedTime()),
192+
er.getJdkVersion()});
193+
}
194+
195+
String[][] table = new String[arrayList.size()][7];
196+
arrayList.toArray(table);
197+
198+
PrettyTable prettyTable = new PrettyTable(System.out);
199+
prettyTable.print(table);
200+
}
201+
202+
static class ExecuteResult {
203+
204+
private String engine;
205+
private String script;
206+
private String bindParam;
207+
private int executeCount;
208+
private String executeType;
209+
private long usedTime;
210+
private String jdkVersion;
211+
212+
public ExecuteResult() {
213+
this.jdkVersion = System.getProperty("java.version");
214+
}
215+
216+
public String getEngine() {
217+
return engine;
218+
}
219+
public void setEngine(String engine) {
220+
this.engine = engine;
221+
}
222+
public String getScript() {
223+
return script;
224+
}
225+
public void setScript(String script) {
226+
this.script = script;
227+
}
228+
public String getBindParam() {
229+
return bindParam;
230+
}
231+
public void setBindParam(String bindParam) {
232+
this.bindParam = bindParam;
233+
}
234+
public int getExecuteCount() {
235+
return executeCount;
236+
}
237+
public void setExecuteCount(int executeCount) {
238+
this.executeCount = executeCount;
239+
}
240+
public String getExecuteType() {
241+
return executeType;
242+
}
243+
public void setExecuteType(String executeType) {
244+
this.executeType = executeType;
245+
}
246+
public long getUsedTime() {
247+
return usedTime;
248+
}
249+
public void setUsedTime(long usedTime) {
250+
this.usedTime = usedTime;
251+
}
252+
public String getJdkVersion() {
253+
return jdkVersion;
254+
}
255+
public void setJdkVersion(String jdkVersion) {
256+
this.jdkVersion = jdkVersion;
257+
}
109258
}
110259

111260
}
Lines changed: 125 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,125 @@
1+
package cn.aofeng.demo.script;
2+
3+
import java.io.PrintStream;
4+
import static java.lang.String.format;
5+
6+
/**
7+
* 此代码来自于网络。使用示例:
8+
* <pre>
9+
* PrettyTable printer = new PrettyTable(out);
10+
* printer.print(new String[][] {
11+
* new String[] {"FIRST NAME", "LAST NAME", "DATE OF BIRTH", "NOTES"},
12+
* new String[] {"Joe", "Smith", "November 2, 1972"},
13+
* null,
14+
* new String[] {"John", "Doe", "April 29, 1970", "Big Brother"},
15+
* new String[] {"Jack", null, null, "(yes, no last name)"}
16+
* });
17+
</pre>
18+
*/
19+
public final class PrettyTable {
20+
21+
private static final char BORDER_KNOT = '+';
22+
private static final char HORIZONTAL_BORDER = '-';
23+
private static final char VERTICAL_BORDER = '|';
24+
25+
private static final String DEFAULT_AS_NULL = "(NULL)";
26+
27+
private final PrintStream out;
28+
private final String asNull;
29+
30+
public PrettyTable(PrintStream out) {
31+
this(out, DEFAULT_AS_NULL);
32+
}
33+
34+
public PrettyTable(PrintStream out, String asNull) {
35+
if ( out == null ) {
36+
throw new IllegalArgumentException("No print stream provided");
37+
}
38+
if ( asNull == null ) {
39+
throw new IllegalArgumentException("No NULL-value placeholder provided");
40+
}
41+
this.out = out;
42+
this.asNull = asNull;
43+
}
44+
45+
public void print(String[][] table) {
46+
if ( table == null ) {
47+
throw new IllegalArgumentException("No tabular data provided");
48+
}
49+
if ( table.length == 0 ) {
50+
return;
51+
}
52+
final int[] widths = new int[getMaxColumns(table)];
53+
adjustColumnWidths(table, widths);
54+
printPreparedTable(table, widths, getHorizontalBorder(widths));
55+
}
56+
57+
private void printPreparedTable(String[][] table, int widths[], String horizontalBorder) {
58+
final int lineLength = horizontalBorder.length();
59+
out.println(horizontalBorder);
60+
for ( final String[] row : table ) {
61+
if ( row != null ) {
62+
out.println(getRow(row, widths, lineLength));
63+
out.println(horizontalBorder);
64+
}
65+
}
66+
}
67+
68+
private String getRow(String[] row, int[] widths, int lineLength) {
69+
final StringBuilder builder = new StringBuilder(lineLength).append(VERTICAL_BORDER);
70+
final int maxWidths = widths.length;
71+
for ( int i = 0; i < maxWidths; i++ ) {
72+
builder.append(padRight(getCellValue(safeGet(row, i, null)), widths[i])).append(VERTICAL_BORDER);
73+
}
74+
return builder.toString();
75+
}
76+
77+
private String getHorizontalBorder(int[] widths) {
78+
final StringBuilder builder = new StringBuilder(256);
79+
builder.append(BORDER_KNOT);
80+
for ( final int w : widths ) {
81+
for ( int i = 0; i < w; i++ ) {
82+
builder.append(HORIZONTAL_BORDER);
83+
}
84+
builder.append(BORDER_KNOT);
85+
}
86+
return builder.toString();
87+
}
88+
89+
private int getMaxColumns(String[][] rows) {
90+
int max = 0;
91+
for ( final String[] row : rows ) {
92+
if ( row != null && row.length > max ) {
93+
max = row.length;
94+
}
95+
}
96+
return max;
97+
}
98+
99+
private void adjustColumnWidths(String[][] rows, int[] widths) {
100+
for ( final String[] row : rows ) {
101+
if ( row != null ) {
102+
for ( int c = 0; c < widths.length; c++ ) {
103+
final String cv = getCellValue(safeGet(row, c, asNull));
104+
final int l = cv.length();
105+
if ( widths[c] < l ) {
106+
widths[c] = l;
107+
}
108+
}
109+
}
110+
}
111+
}
112+
113+
private static String padRight(String s, int n) {
114+
return format("%1$-" + n + "s", s);
115+
}
116+
117+
private static String safeGet(String[] array, int index, String defaultValue) {
118+
return index < array.length ? array[index] : defaultValue;
119+
}
120+
121+
private String getCellValue(Object value) {
122+
return value == null ? asNull : value.toString();
123+
}
124+
125+
}

0 commit comments

Comments
 (0)