All Downloads are FREE. Search and download functionalities are using the official Maven repository.

test.TestTypedSpeed Maven / Gradle / Ivy

There is a newer version: 1.3.3
Show newest version
package test;

import java.io.*;

import javax.xml.stream.*;

import org.codehaus.stax2.*;

/**
 * Simple typed information access stress test, useful for profiling, as well
 * as for
 * quickly checking high-level performance effects of changes (albeit
 * not very accurately, obviously -- need longer running composite
 * tests for such verifications).
 *

* Type of data is auto-detected, and is assumed to be homogenous. Basically, * data is either within attributes, or as element content, but not both. * In either case structure should be shallow, with the root and only * immediate leaf-level elements containing attribute or element data. * Type of this data is auto-detected from the first instance; data must * be in canonical format to be properly recognized (non-first values * can be non-canonical). */ public class TestTypedSpeed implements XMLStreamConstants { /** * Number of repetitions to run per test. Dynamically variable, * based on observed runtime, to try to keep it high enough. */ private int REPS; private final static int TEST_PER_GC = 7; final static int TYPE_BOOLEAN = 1; final static int TYPE_INT = 1; /** * Let's keep per-run times above 50 milliseconds */ //final static int MIN_RUN_TIME = 50; final static int MIN_RUN_TIME = 5; /** * Let's keep per-run times below 300 milliseconds */ //final static int MAX_RUN_TIME = 300; final static int MAX_RUN_TIME = 1000; final XMLInputFactory mInputFactory; final ByteArrayInputStream mIn; /** * Data in attributes? If true, yes; if no, in elements */ boolean mUseAttr; int mType; private TestTypedSpeed(byte[] data) { mInputFactory = new com.fasterxml.aalto.stax.InputFactoryImpl(); mInputFactory.setProperty(XMLInputFactory.IS_COALESCING, Boolean.FALSE); mInputFactory.setProperty(XMLInputFactory.IS_NAMESPACE_AWARE, Boolean.TRUE); // Just in case: mInputFactory.setProperty(XMLInputFactory.SUPPORT_DTD, Boolean.FALSE); mIn = new ByteArrayInputStream(data); // Ok how should we guestimate speed... perhaps from data size? REPS = 100 + ((8 * 1000 * 1000) / data.length); System.out.println("Based on size, will use "+REPS+" repetitions"); } protected int test() throws Exception { /* First things first: let's determine how data is stored, * as well as what's the first (canonical) value */ mIn.reset(); String firstValue = findFirstValue(mIn); // also sets/clear 'mUseAttr' flag if (mUseAttr) { REPS += REPS; System.out.println("(data stored as attributes: doubling REPS to "+REPS+")"); } else { System.out.println("(data stored as element content)"); } // But how about type? mType = 0; if ("true".equals(firstValue) || "false".equals(firstValue)) { mType = TYPE_BOOLEAN; System.out.println("Type detected as: BOOLEAN"); } else { try { /*int nr =*/ Integer.parseInt(firstValue); // Ok, was a valid int mType = TYPE_BOOLEAN; System.out.println("Type detected as: INT"); } catch (NumberFormatException nex) { } } if (mType == 0) { throw new IllegalArgumentException("Can not auto-detect type from value '"+firstValue+"'"); } return test2(); } private String findFirstValue(InputStream in) throws XMLStreamException { XMLStreamReader sr = mInputFactory.createXMLStreamReader(in); sr.nextTag(); sr.nextTag(); String value; if (sr.getAttributeCount() > 0) { // attributes mUseAttr = true; value = sr.getAttributeValue(0); } else { mUseAttr = false; value = sr.getElementText(); } sr.close(); return value; } private int test2() throws Exception { int i = 0; int total = 0; final int TEST_CASES = 2; while (true) { try { Thread.sleep(150L); } catch (InterruptedException ie) { } int round = (i++ % TEST_CASES); long now = System.currentTimeMillis(); String msg; int sum = 0; switch (round) { case 0: msg = "Access using Stax 1.0"; switch (mType) { case TYPE_BOOLEAN: sum = mUseAttr ? testUntypedBooleanAttr(REPS) : testUntypedBooleanElem(REPS); break; /* case TYPE_INT: sum = mUseAttr ? testUntypedIntAttr(REPS) : testUntypedIntElem(REPS); break; */ default: throw new Error("Internal error"); } break; case 1: msg = "Access using Stax2 Typed API"; switch (mType) { case TYPE_BOOLEAN: sum = mUseAttr ? testTypedBooleanAttr(REPS) : testTypedBooleanElem(REPS); break; /* case TYPE_INT: sum = mUseAttr ? testTypedIntAttr(REPS) : testTypedIntElem(REPS); break; */ default: throw new Error("Internal error"); } break; default: throw new Error("Internal error"); } now = System.currentTimeMillis() - now; if (round == 0) { System.out.println(); } System.out.println("Test '"+msg+"' -> "+now+" msecs (" +sum+" -> "+(total & 0xFF)+")."); total += sum; if ((i % TEST_PER_GC) == 0) { System.out.println("[GC]"); try { Thread.sleep(100L); } catch (InterruptedException ie) { } System.gc(); try { Thread.sleep(200L); } catch (InterruptedException ie) { } /* One more tweak: let's add load if things start * running too fast or slow, to try to get sweet range * of 50 to 250 millisseconds */ if (now < MIN_RUN_TIME) { REPS += (REPS / 5); // 20% up System.out.println("[NOTE: increasing reps, now: "+REPS+"]"); try { Thread.sleep(200L); } catch (InterruptedException ie) { } } else if (now > MAX_RUN_TIME && i > 20) { /* Let's reduce load slower than increase; also, * due to initial warmup, let's not adjust until * we've gone through a few cycles */ REPS -= (REPS / 10); // 10% down System.out.println("[NOTE: decreasing reps, now: "+REPS+"]"); try { Thread.sleep(200L); } catch (InterruptedException ie) { } } } } } /* ///////////////////////////////////////////////////////// // Actual value type access, ones via Stax 1.0 ///////////////////////////////////////////////////////// */ protected int testUntypedBooleanAttr(int reps) throws Exception { int total = 0; for (int i = 0; i < reps; ++i) { XMLStreamReader2 sr = constructAndFindRoot(); while (sr.nextTag() == START_ELEMENT) { int c = sr.getAttributeCount(); while (--c >= 0) { String str = sr.getAttributeValue(c).trim(); if (str.equals("true")) { ++total; } else if (str.equals("false") || str.equals("0")) { ; } else if (str.equals("1")) { ++total; } else { throw new XMLStreamException("Illegal value '"+str+"', not boolean"); } } } sr.close(); } return total; } protected int testUntypedBooleanElem(int reps) throws Exception { int total = 0; for (int i = 0; i < reps; ++i) { XMLStreamReader2 sr = constructAndFindRoot(); while (sr.nextTag() == START_ELEMENT) { String str = sr.getElementText().trim(); if (str.equals("true")) { ++total; } else if (str.equals("false") || str.equals("0")) { ; } else if (str.equals("1")) { ++total; } else { throw new XMLStreamException("Illegal value '"+str+"', not boolean"); } } sr.close(); } return total; } /* ///////////////////////////////////////////////////////// // Actual value type access, ones via Stax2 Typed API ///////////////////////////////////////////////////////// */ protected int testTypedBooleanAttr(int reps) throws Exception { int total = 0; for (int i = 0; i < reps; ++i) { XMLStreamReader2 sr = constructAndFindRoot(); while (sr.nextTag() == START_ELEMENT) { int c = sr.getAttributeCount(); while (--c >= 0) { if (sr.getAttributeAsBoolean(c)) { ++total; } } } sr.close(); } return total; } protected int testTypedBooleanElem(int reps) throws Exception { int total = 0; for (int i = 0; i < reps; ++i) { XMLStreamReader2 sr = constructAndFindRoot(); while (sr.nextTag() == START_ELEMENT) { if (sr.getElementAsBoolean()) { ++total; } } sr.close(); } return total; } /* ///////////////////////////////////////////////////////// // Helper methods ///////////////////////////////////////////////////////// */ XMLStreamReader2 constructAndFindRoot() throws XMLStreamException { mIn.reset(); XMLStreamReader sr = mInputFactory.createXMLStreamReader(mIn); if (sr.nextTag() != START_ELEMENT) { throw new XMLStreamException("Couldn't locate root"); } ; // points to root now return (XMLStreamReader2) sr; } static byte[] readData(File file) throws IOException { InputStream fin = new FileInputStream(file); byte[] buf = new byte[4000]; ByteArrayOutputStream bos = new ByteArrayOutputStream(4000); int count; while ((count = fin.read(buf)) > 0) { bos.write(buf, 0, count); } fin.close(); return bos.toByteArray(); } public static void main(String[] args) throws Exception { if (args.length != 1) { System.err.println("Usage: java ... "); System.exit(1); } byte[] data = readData(new File(args[0])); System.out.println(" -> "+data.length+" bytes read."); new TestTypedSpeed(data).test(); } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy