gt: 			long end = currentTimeMillis();
context: /*
   Copyright (c) 2002, 2010, Oracle and/or its affiliates. All rights reserved.
   
  
    The MySQL Connector/J is licensed under the terms of the GPLv2
    <http://www.gnu.org/licenses/old-licenses/gpl-2.0.html>, like most MySQL Connectors.
    There are special exceptions to the terms and conditions of the GPLv2 as it is applied to
    this software, see the FLOSS License Exception
    <http://www.mysql.com/about/legal/licensing/foss-exception.html>.
  
    This program is free software; you can redistribute it and/or modify it under the terms
    of the GNU General Public License as published by the Free Software Foundation; version 2
    of the License.
  
    This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
    without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
    See the GNU General Public License for more details.
  
    You should have received a copy of the GNU General Public License along with this
    program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth
    Floor, Boston, MA 02110-1301  USA
  
  
  
   */
  package testsuite.regression;
  
  import java.sql.Date;
  import java.sql.PreparedStatement;
  import java.sql.Time;
  import java.sql.Timestamp;
  import java.util.HashMap;
  import java.util.Map;
  
  import testsuite.BaseTestCase;
  
  /**
   * Microperformance benchmarks to track increase/decrease in performance of core
   * methods in the driver over time.
   * 
   * @author Mark Matthews
   * 
   * @version $Id: MicroPerformanceRegressionTest.java,v 1.1.2.1 2005/05/13
   *          18:58:38 mmatthews Exp $
   */
  public class MicroPerformanceRegressionTest extends BaseTestCase {
  
  	private double scaleFactor = 1.0;
  
  	private final static int ORIGINAL_LOOP_TIME_MS = 2300;
  
  	private final static double LEEWAY = 10.0; // account for VMs
  
  	private final static Map BASELINE_TIMES = new HashMap();
  
  	static {
  		BASELINE_TIMES.put("ResultSet.getInt()", new Double(0.00661));
  		BASELINE_TIMES.put("ResultSet.getDouble()", new Double(0.00671));
  		BASELINE_TIMES.put("ResultSet.getTime()", new Double(0.02033));
  		BASELINE_TIMES.put("ResultSet.getTimestamp()", new Double(0.02363));
  		BASELINE_TIMES.put("ResultSet.getDate()", new Double(0.02223));
  		BASELINE_TIMES.put("ResultSet.getString()", new Double(0.00982));
  		BASELINE_TIMES.put("ResultSet.getObject() on a string", new Double(
  				0.00861));
  		BASELINE_TIMES
  				.put("Connection.prepareStatement()", new Double(0.18547));
  		BASELINE_TIMES.put("single selects", new Double(46));
  		BASELINE_TIMES.put("5 standalone queries", new Double(146));
  		BASELINE_TIMES.put("total time all queries", new Double(190));
  		if (com.mysql.jdbc.Util.isJdbc4()) {
  			BASELINE_TIMES
  					.put("PreparedStatement.setInt()", new Double(0.0014));
  			BASELINE_TIMES.put("PreparedStatement.setTime()",
  					new Double(0.0107));
  			BASELINE_TIMES.put("PreparedStatement.setTimestamp()", new Double(
  					0.0182));
  			BASELINE_TIMES.put("PreparedStatement.setDate()",
  					new Double(0.0819));
  			BASELINE_TIMES.put("PreparedStatement.setString()", new Double(
  					0.0081));
  			BASELINE_TIMES.put("PreparedStatement.setObject() on a string",
  					new Double(0.00793));
  			BASELINE_TIMES.put("PreparedStatement.setDouble()", new Double(
  					0.0246));
  		} else {
  			BASELINE_TIMES
  					.put("PreparedStatement.setInt()", new Double(0.0011));
  			BASELINE_TIMES.put("PreparedStatement.setTime()",
  					new Double(0.0642));
  			BASELINE_TIMES.put("PreparedStatement.setTimestamp()", new Double(
  					0.03184));
  			BASELINE_TIMES.put("PreparedStatement.setDate()", new Double(
  					0.12248));
  			BASELINE_TIMES.put("PreparedStatement.setString()", new Double(
  					0.01512));
  			BASELINE_TIMES.put("PreparedStatement.setObject() on a string",
  					new Double(0.01923));
  			BASELINE_TIMES.put("PreparedStatement.setDouble()", new Double(
  					0.00671));
  		}
  	}
  
  	public MicroPerformanceRegressionTest(String name) {
  		super(name);
  	}
  
  	/**
  	 * Runs all test cases in this test suite
  	 * 
  	 * @param args
  	 */
  	public static void main(String[] args) {
  		junit.textui.TestRunner.run(MicroPerformanceRegressionTest.class);
  	}
  
  	/**
  	 * Tests result set accessors performance.
  	 * 
  	 * @throws Exception
  	 *             if the performance of these methods does not meet
  	 *             expectations.
  	 */
  	public void testResultSetAccessors() throws Exception {
  		createTable(
  				"marktest",
  				"(intField INT, floatField DOUBLE, timeField TIME, datetimeField DATETIME, stringField VARCHAR(64))");
  		this.stmt
  				.executeUpdate("INSERT INTO marktest VALUES (123456789, 12345.6789, NOW(), NOW(), 'abcdefghijklmnopqrstuvABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@')");
  
  		this.rs = this.stmt
  				.executeQuery("SELECT intField, floatField, timeField, datetimeField, stringField FROM marktest");
  
  		this.rs.next();
  
  		int numLoops = 100000;
  
  		long start = currentTimeMillis();
  
  		for (int i = 0; i < numLoops; i++) {
  			this.rs.getInt(1);
  		}
  
  		double getIntAvgMs = (double) (currentTimeMillis() - start) / numLoops;
  
  		checkTime("ResultSet.getInt()", getIntAvgMs);
  
  		start = currentTimeMillis();
  
  		for (int i = 0; i < numLoops; i++) {
  			this.rs.getDouble(2);
  		}
  
  		double getDoubleAvgMs = (double) (currentTimeMillis() - start)
  				/ numLoops;
  
  		checkTime("ResultSet.getDouble()", getDoubleAvgMs);
  
  		start = currentTimeMillis();
  
  		for (int i = 0; i < numLoops; i++) {
  			this.rs.getTime(3);
  		}
  
  		double getTimeAvgMs = (double) (currentTimeMillis() - start) / numLoops;
  
  		checkTime("ResultSet.getTime()", getTimeAvgMs);
  
  		start = currentTimeMillis();
  
  		for (int i = 0; i < numLoops; i++) {
  			this.rs.getTimestamp(4);
  		}
  
  		double getTimestampAvgMs = (double) (currentTimeMillis() - start)
  				/ numLoops;
  
  		checkTime("ResultSet.getTimestamp()", getTimestampAvgMs);
  
  		start = currentTimeMillis();
  
  		for (int i = 0; i < numLoops; i++) {
  			this.rs.getDate(4);
  		}
  
  		double getDateAvgMs = (double) (currentTimeMillis() - start) / numLoops;
  
  		checkTime("ResultSet.getDate()", getDateAvgMs);
  
  		start = currentTimeMillis();
  
  		for (int i = 0; i < numLoops; i++) {
  			this.rs.getString(5);
  		}
  
  		double getStringAvgMs = (double) (currentTimeMillis() - start)
  				/ numLoops;
  
  		checkTime("ResultSet.getString()", getStringAvgMs);
  
  		start = currentTimeMillis();
  
  		for (int i = 0; i < numLoops; i++) {
  			this.rs.getObject(5);
  		}
  
  		double getStringObjAvgMs = (double) (currentTimeMillis() - start)
  				/ numLoops;
  
  		checkTime("ResultSet.getObject() on a string", getStringObjAvgMs);
  	}
  
  	public void testPreparedStatementTimes() throws Exception {
  		createTable(
  				"marktest",
  				"(intField INT, floatField DOUBLE, timeField TIME, datetimeField DATETIME, stringField VARCHAR(64))");
  		this.stmt
  				.executeUpdate("INSERT INTO marktest VALUES (123456789, 12345.6789, NOW(), NOW(), 'abcdefghijklmnopqrstuvABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@')");
  
  		long start = currentTimeMillis();
  
  		long blockStart = currentTimeMillis();
  		long lastBlock = 0;
  
  		int numLoops = 100000;
  
  		int numPrepares = 100000;
  
  		if (versionMeetsMinimum(4, 1)) {
  			numPrepares = 10000; // we don't need to do so many for
  			// server-side prep statements...
  		}
  
  		for (int i = 0; i < numPrepares; i++) {
  			if (i % 1000 == 0) {
  
  				long blockEnd = currentTimeMillis();
  
  				long totalTime = blockEnd - blockStart;
  
  				blockStart = blockEnd;
  
  				StringBuffer messageBuf = new StringBuffer();
  
  				messageBuf.append(i + " prepares, the last 1000 prepares took "
  						+ totalTime + " ms");
  
  				if (lastBlock == 0) {
  					lastBlock = totalTime;
  					messageBuf.append(".");
  				} else {
  					double diff = (double) totalTime / (double) lastBlock;
  
  					messageBuf.append(", difference is " + diff + " x");
  
  					lastBlock = totalTime;
  				}
  
  				System.out.println(messageBuf.toString());
  
  			}
  
  			PreparedStatement pStmt = this.conn
  					.prepareStatement("INSERT INTO test.marktest VALUES (?, ?, ?, ?, ?)");
  			pStmt.close();
  		}
  
  		double getPrepareStmtAvgMs = (double) (currentTimeMillis() - start)
  				/ numPrepares;
  
  		// checkTime("Connection.prepareStatement()", getPrepareStmtAvgMs);
  
  		PreparedStatement pStmt = this.conn
  				.prepareStatement("INSERT INTO marktest VALUES (?, ?, ?, ?, ?)");
  
  		System.out.println(pStmt.toString());
  
  		start = currentTimeMillis();
  
  		for (int i = 0; i < numLoops; i++) {
  			pStmt.setInt(1, 1);
  		}
  
  		System.out.println(pStmt.toString());
  
  		double setIntAvgMs = (double) (currentTimeMillis() - start) / numLoops;
  
  		checkTime("PreparedStatement.setInt()", setIntAvgMs);
  
  		start = currentTimeMillis();
  
  		for (int i = 0; i < numLoops; i++) {
  			pStmt.setDouble(2, 1234567890.1234);
  		}
  
  		double setDoubleAvgMs = (double) (currentTimeMillis() - start)
  				/ numLoops;
  
  		checkTime("PreparedStatement.setDouble()", setDoubleAvgMs);
  
  		start = currentTimeMillis();
  
  		Time tm = new Time(start);
  
  		for (int i = 0; i < numLoops; i++) {
  			pStmt.setTime(3, tm);
  		}
  
  		double setTimeAvgMs = (double) (currentTimeMillis() - start) / numLoops;
  
  		checkTime("PreparedStatement.setTime()", setTimeAvgMs);
  
  		start = currentTimeMillis();
  
  		Timestamp ts = new Timestamp(start);
  
  		for (int i = 0; i < numLoops; i++) {
  			pStmt.setTimestamp(4, ts);
  		}
  
  		double setTimestampAvgMs = (double) (currentTimeMillis() - start)
  				/ numLoops;
  
  		checkTime("PreparedStatement.setTimestamp()", setTimestampAvgMs);
  
  		start = currentTimeMillis();
  
  		Date dt = new Date(start);
  
  		for (int i = 0; i < numLoops; i++) {
  			pStmt.setDate(4, dt);
  		}
  
  		double setDateAvgMs = (double) (currentTimeMillis() - start) / numLoops;
  
  		checkTime("PreparedStatement.setDate()", setDateAvgMs);
  
  		start = currentTimeMillis();
  
  		for (int i = 0; i < numLoops; i++) {
  			pStmt.setString(5,
  					"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@");
  		}
  
  		double setStringAvgMs = (double) (currentTimeMillis() - start)
  				/ numLoops;
  
  		checkTime("PreparedStatement.setString()", setStringAvgMs);
  
  		start = currentTimeMillis();
  
  		for (int i = 0; i < numLoops; i++) {
  			pStmt.setObject(5,
  					"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@");
  		}
  
  		double setStringObjAvgMs = (double) (currentTimeMillis() - start)
  				/ numLoops;
  
  		checkTime("PreparedStatement.setObject() on a string",
  				setStringObjAvgMs);
  
  		start = currentTimeMillis();
  	}
  
  	/*
  	 * (non-Javadoc)
  	 * 
  	 * @see junit.framework.TestCase#setUp()
  	 */
  	public void setUp() throws Exception {
  		super.setUp();
  
  		System.out.println("Calculating performance scaling factor...");
  		// Run this simple test to get some sort of performance scaling factor,
  		// compared to
  		// the development environment. This should help reduce false-positives
  		// on this test.
  		int numLoops = 10000;
  
  		long start = currentTimeMillis();
  
  		for (int j = 0; j < 2000; j++) {
  			StringBuffer buf = new StringBuffer(numLoops);
  
  			for (int i = 0; i < numLoops; i++) {
  				buf.append('a');
  			}
  		}
  
  		long elapsedTime = currentTimeMillis() - start;
  
  		System.out.println("Elapsed time for factor: " + elapsedTime);
  
  		this.scaleFactor = (double) elapsedTime
  				/ (double) ORIGINAL_LOOP_TIME_MS;
  
  		System.out
  				.println("Performance scaling factor is: " + this.scaleFactor);
  	}
  
  	private void checkTime(String testType, double avgExecTimeMs)
  			throws Exception {
  
  		double adjustForVendor = 1.0D;
  
  		if (isRunningOnJRockit()) {
  			adjustForVendor = 4.0D;
  		}
  
  		Double baselineExecTimeMs = (Double) BASELINE_TIMES.get(testType);
  
  		if (baselineExecTimeMs == null) {
  			throw new Exception("No baseline time recorded for test '"
  					+ testType + "'");
  		}
  
  		double acceptableTime = LEEWAY * baselineExecTimeMs.doubleValue()
  				* this.scaleFactor * adjustForVendor;
  
  		assertTrue("Average execution time of " + avgExecTimeMs
  				+ " ms. exceeded baseline * leeway of " + acceptableTime
  				+ " ms.", (avgExecTimeMs <= acceptableTime));
  	}
  
  	public void testBug6359() throws Exception {
  		if (runLongTests()) {
  			int numRows = 550000;
  			int numSelects = 100000;
  
  			createTable(
  					"testBug6359",
  					"(pk_field INT PRIMARY KEY NOT NULL AUTO_INCREMENT, field1 INT, field2 INT, field3 INT, field4 INT, field5 INT, field6 INT, field7 INT, field8 INT, field9 INT,  INDEX (field1))");
  
  			PreparedStatement pStmt = this.conn
  					.prepareStatement("INSERT INTO testBug6359 (field1, field2, field3, field4, field5, field6, field7, field8, field9) VALUES (?, 1, 2, 3, 4, 5, 6, 7, 8)");
  
  			logDebug("Loading " + numRows + " rows...");
  
  			for (int i = 0; i < numRows; i++) {
  				pStmt.setInt(1, i);
  				pStmt.executeUpdate();
  
  				if ((i % 10000) == 0) {
  					logDebug(i + " rows loaded so far");
  				}
  			}
  
  			logDebug("Finished loading rows");
  
  			long begin = currentTimeMillis();
  
  			long beginSingleQuery = currentTimeMillis();
  
  			for (int i = 0; i < numSelects; i++) {
  				this.rs = this.stmt
  						.executeQuery("SELECT pk_field FROM testBug6359 WHERE field1 BETWEEN 1 AND 5");
  			}
  
  			long endSingleQuery = currentTimeMillis();
  
  			double secondsSingleQuery = ((double) endSingleQuery - (double) beginSingleQuery) / 1000;
  
  			logDebug("time to execute " + numSelects + " single queries: "
  					+ secondsSingleQuery + " seconds");
  
  			checkTime("single selects", secondsSingleQuery);
  
  			PreparedStatement pStmt2 = this.conn
  					.prepareStatement("SELECT field2, field3, field4, field5 FROM testBug6359 WHERE pk_field=?");
  
  			long beginFiveQueries = currentTimeMillis();
  
  			for (int i = 0; i < numSelects; i++) {
  
  				for (int j = 0; j < 5; j++) {
  					pStmt2.setInt(1, j);
  					pStmt2.executeQuery();
  				}
  			}
  
  			long endFiveQueries = currentTimeMillis();
  
  			double secondsFiveQueries = ((double) endFiveQueries - (double) beginFiveQueries) / 1000;
  
  			logDebug("time to execute " + numSelects
  					+ " 5 standalone queries: " + secondsFiveQueries
  					+ " seconds");
  
  			checkTime("5 standalone queries", secondsFiveQueries);
  
  