/* * Copyright 2004-2011 H2 Group. Multiple-Licensed under the H2 License, * Version 1.0, and under the Eclipse Public License, Version 1.0 * (http://h2database.com/html/license.html). * Initial Developer: H2 Group */ package org.h2.test.bench; import java.io.FileWriter; import java.io.InputStream; import java.io.PrintWriter; import java.sql.Connection; import java.sql.DatabaseMetaData; import java.sql.DriverManager; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Statement; import java.util.ArrayList; import java.util.Properties; import org.h2.store.fs.FileUtils; import org.h2.test.TestBase; import org.h2.util.IOUtils; import org.h2.util.JdbcUtils; /** * The main controller class of the benchmark application. * To run the benchmark, call the main method of this class. */ public class TestPerformance { /** * Whether data should be collected. */ boolean collect; /** * The flag used to enable or disable trace messages. */ boolean trace; /** * This method is called when executing this sample application. * * @param args the command line parameters */ public static void main(String... args) throws Exception { new TestPerformance().test(args); } private static Connection getResultConnection() throws SQLException { org.h2.Driver.load(); return DriverManager.getConnection("jdbc:h2:data/results"); } private static void openResults() throws SQLException { Connection conn = null; Statement stat = null; try { conn = getResultConnection(); stat = conn.createStatement(); stat.execute("CREATE TABLE IF NOT EXISTS RESULTS(TESTID INT, TEST VARCHAR, " + "UNIT VARCHAR, DBID INT, DB VARCHAR, RESULT VARCHAR)"); } finally { JdbcUtils.closeSilently(stat); JdbcUtils.closeSilently(conn); } } private void test(String... args) throws Exception { int dbId = -1; boolean exit = false; String out = "benchmark.html"; for (int i = 0; i < args.length; i++) { String arg = args[i]; if ("-db".equals(arg)) { dbId = Integer.parseInt(args[++i]); } else if ("-init".equals(arg)) { FileUtils.deleteRecursive("data", true); } else if ("-out".equals(arg)) { out = args[++i]; } else if ("-trace".equals(arg)) { trace = true; } else if ("-exit".equals(arg)) { exit = true; } } Properties prop = new Properties(); InputStream in = getClass().getResourceAsStream("test.properties"); prop.load(in); in.close(); int size = Integer.parseInt(prop.getProperty("size")); ArrayList<Database> dbs = new ArrayList<Database>(); for (int i = 0; i < 100; i++) { if (dbId != -1 && i != dbId) { continue; } String dbString = prop.getProperty("db" + i); if (dbString != null) { Database db = Database.parse(this, i, dbString); if (db != null) { db.setTranslations(prop); dbs.add(db); } } } ArrayList<Bench> tests = new ArrayList<Bench>(); for (int i = 0; i < 100; i++) { String testString = prop.getProperty("test" + i); if (testString != null) { Bench bench = (Bench) Class.forName(testString).newInstance(); tests.add(bench); } } testAll(dbs, tests, size); collect = false; if (dbs.size() == 0) { return; } ArrayList<Object[]> results = dbs.get(0).getResults(); Connection conn = null; PreparedStatement prep = null; Statement stat = null; PrintWriter writer = null; try { openResults(); conn = getResultConnection(); stat = conn.createStatement(); prep = conn .prepareStatement("INSERT INTO RESULTS(TESTID, TEST, UNIT, DBID, DB, RESULT) VALUES(?, ?, ?, ?, ?, ?)"); for (int i = 0; i < results.size(); i++) { Object[] res = results.get(i); prep.setInt(1, i); prep.setString(2, res[0].toString()); prep.setString(3, res[1].toString()); for (Database db : dbs) { prep.setInt(4, db.getId()); prep.setString(5, db.getName()); Object[] v = db.getResults().get(i); prep.setString(6, v[2].toString()); prep.execute(); } } writer = new PrintWriter(new FileWriter(out)); ResultSet rs = stat.executeQuery( "CALL '<table><tr><th>Test Case</th><th>Unit</th>' " +"|| SELECT GROUP_CONCAT('<th>' || DB || '</th>' ORDER BY DBID SEPARATOR '') FROM " +"(SELECT DISTINCT DBID, DB FROM RESULTS)" +"|| '</tr>' || CHAR(10) " +"|| SELECT GROUP_CONCAT('<tr><td>' || TEST || '</td><td>' || UNIT || '</td>' || ( " +"SELECT GROUP_CONCAT('<td>' || RESULT || '</td>' ORDER BY DBID SEPARATOR '') FROM RESULTS R2 WHERE " +"R2.TESTID = R1.TESTID) || '</tr>' ORDER BY TESTID SEPARATOR CHAR(10)) FROM " +"(SELECT DISTINCT TESTID, TEST, UNIT FROM RESULTS) R1" +"|| '</table>'" ); rs.next(); String result = rs.getString(1); writer.println(result); } finally { JdbcUtils.closeSilently(prep); JdbcUtils.closeSilently(stat); JdbcUtils.closeSilently(conn); IOUtils.closeSilently(writer); } // ResultSet rsDbs = conn.createStatement().executeQuery( // "SELECT DB RESULTS GROUP BY DBID, DB ORDER BY DBID"); // while(rsDbs.next()) { // writer.println("<th>" + rsDbs.getString(1) + "</th>"); // } // ResultSet rs = conn.createStatement().executeQuery( // "SELECT TEST, UNIT FROM RESULTS " + // "GROUP BY TESTID, TEST, UNIT ORDER BY TESTID"); // while(rs.next()) { // writer.println("<tr><td>" + rs.getString(1) + "</td>"); // writer.println("<td>" + rs.getString(2) + "</td>"); // ResultSet rsRes = conn.createStatement().executeQuery( // "SELECT RESULT FROM RESULTS WHERE TESTID=? ORDER BY DBID"); // // // } // PrintWriter writer = // new PrintWriter(new FileWriter("benchmark.html")); // writer.println("<table><tr><th>Test Case</th><th>Unit</th>"); // for(int j=0; j<dbs.size(); j++) { // Database db = (Database)dbs.get(j); // writer.println("<th>" + db.getName() + "</th>"); // } // writer.println("</tr>"); // for(int i=0; i<results.size(); i++) { // Object[] res = (Object[])results.get(i); // writer.println("<tr><td>" + res[0] + "</td>"); // writer.println("<td>" + res[1] + "</td>"); // for(int j=0; j<dbs.size(); j++) { // Database db = (Database)dbs.get(j); // ArrayList r = db.getResults(); // Object[] v = (Object[])r.get(i); // writer.println( // "<td style=\"text-align: right\">" + v[2] + "</td>"); // } // writer.println("</tr>"); // } // writer.println("</table>"); if (exit) { System.exit(0); } } private void testAll(ArrayList<Database> dbs, ArrayList<Bench> tests, int size) throws Exception { for (int i = 0; i < dbs.size(); i++) { if (i > 0) { Thread.sleep(1000); } // calls garbage collection TestBase.getMemoryUsed(); Database db = dbs.get(i); System.out.println("Testing the performance of " + db.getName()); db.startServer(); Connection conn = db.openNewConnection(); DatabaseMetaData meta = conn.getMetaData(); System.out.println(" " + meta.getDatabaseProductName() + " " + meta.getDatabaseProductVersion()); runDatabase(db, tests, 1); runDatabase(db, tests, 1); collect = true; runDatabase(db, tests, size); conn.close(); db.log("Executed statements", "#", db.getExecutedStatements()); db.log("Total time", "ms", db.getTotalTime()); int statPerSec = db.getExecutedStatements() * 1000 / db.getTotalTime(); db.log("Statements per second", "#", statPerSec); System.out.println("Statements per second: " + statPerSec); collect = false; db.stopServer(); } } private static void runDatabase(Database db, ArrayList<Bench> tests, int size) throws Exception { for (Bench bench : tests) { runTest(db, bench, size); } } private static void runTest(Database db, Bench bench, int size) throws Exception { bench.init(db, size); bench.runTest(); } /** * Print a message to system out if trace is enabled. * * @param s the message */ void trace(String s) { if (trace) { System.out.println(s); } } }