BinaryXmlIOComparison.java

package gov.usgs.earthquake.product.io;

import gov.usgs.earthquake.product.Product;
import gov.usgs.util.StreamUtils;

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.util.Date;

/**
 * Compare io times of XML and Binary product formats.
 *
 * All conversion is done in memory to try to balance the tests. All writes use
 * a BinaryProductSource to keep the playing field level.
 */
public class BinaryXmlIOComparison {

	/**
	 * Serializes product by streaming it to a handler
	 * @param source a productSource
	 * @param handler a productHandler
	 * @return Time it took to stream source to handler
	 * @throws Exception if error occurs
	 */
	public static long timeSerializeProduct(final ProductSource source,
			final ProductHandler handler) throws Exception {
		Date start = new Date();
		source.streamTo(handler);
		Date end = new Date();
		return end.getTime() - start.getTime();
	}

	/**
	 * Testing for class
	 * @param args CLI args
	 * @throws Exception if error occurs
	 */
	public static void main(final String[] args) throws Exception {
		int numRuns = 10;
		testProductIO(
				ObjectProductHandler.getProduct(new BinaryProductSource(
						StreamUtils.getInputStream(new File(
								"etc/test_products/se082311a/us_dyfi_se082311a_1314562782198.bin")))),
				numRuns);
		testProductIO(
				ObjectProductHandler.getProduct(new BinaryProductSource(
						StreamUtils.getInputStream(new File(
								"etc/test_products/usa00040xz/us_shakemap_usa00040xz_1287260900624.bin")))),
				numRuns);
		testProductIO(
				ObjectProductHandler.getProduct(new BinaryProductSource(
						StreamUtils.getInputStream(new File(
								"etc/test_products/usa00040xz/us_losspager_usa00040xz_1287260989064.bin")))),
				numRuns);
	}

	/**
	 * Tests product IO
	 * @param product Produc
	 * @param numRuns int
	 * @throws Exception if error occurs
	 */
	public static void testProductIO(final Product product, int numRuns)
			throws Exception {
		System.err.println(product.getId().toString());
		testXmlReads(product, numRuns);
		testXmlWrites(product, numRuns);
		testBinaryReads(product, numRuns);
		testBinaryWrites(product, numRuns);
		System.err.println();
	}

	/**
	 * Tests XML reading
	 * @param product a product
	 * @param numReads int
	 * @throws Exception if error occurs
	 */
	public static void testXmlReads(final Product product, int numReads)
			throws Exception {
		// read product into memory
		ByteArrayOutputStream baos = new ByteArrayOutputStream();
		new ObjectProductSource(product).streamTo(new XmlProductHandler(baos));
		byte[] bytes = baos.toByteArray();

		long time = 0L;

		for (int i = 0; i < numReads; i++) {
			Date start = new Date();

			// parse from memory
			ObjectProductHandler.getProduct(new XmlProductSource(StreamUtils
					.getInputStream(bytes)));

			Date end = new Date();
			time += end.getTime() - start.getTime();
		}

		System.err.println("xml\tlength=" + bytes.length + ",\tnumReads="
				+ numReads + ",\tread average=" + ((double) time / numReads));
	}

	/**
	 * Tests binary reading
	 * @param product a product
	 * @param numReads int
	 * @throws Exception if error occurs
	 */
	public static void testBinaryReads(final Product product, int numReads)
			throws Exception {
		// read product into memory
		ByteArrayOutputStream baos = new ByteArrayOutputStream();
		new ObjectProductSource(product)
				.streamTo(new BinaryProductHandler(baos));
		byte[] bytes = baos.toByteArray();

		long time = 0L;

		for (int i = 0; i < numReads; i++) {
			Date start = new Date();

			// parse from memory
			ObjectProductHandler.getProduct(new BinaryProductSource(StreamUtils
					.getInputStream(bytes)));

			Date end = new Date();
			time += end.getTime() - start.getTime();
		}

		System.err.println("binary\tlength=" + bytes.length + ",\tnumReads="
				+ numReads + ",\tread average=" + ((double) time / numReads));
	}

	/**
	 * Tests binary writes
	 * @param product a product
	 * @param numWrites int
	 * @throws Exception if error occurs
	 */
	public static void testBinaryWrites(final Product product, int numWrites)
			throws Exception {
		// read product into memory
		ByteArrayOutputStream baos = new ByteArrayOutputStream();
		new ObjectProductSource(product)
				.streamTo(new BinaryProductHandler(baos));
		byte[] bytes = baos.toByteArray();

		long time = 0L;

		for (int i = 0; i < numWrites; i++) {
			baos.reset();
			Date start = new Date();

			// parse from memory
			new BinaryProductSource(StreamUtils.getInputStream(bytes))
					.streamTo(new BinaryProductHandler(baos));

			Date end = new Date();
			time += end.getTime() - start.getTime();
		}

		System.err.println("binary\tlength=" + baos.toByteArray().length
				+ ",\tnumWrites=" + numWrites + ",\twrite average="
				+ ((double) time / numWrites));
	}

	/**
	 * tests xml writes
	 * @param product a product
	 * @param numWrites int
	 * @throws Exception if error occurs
	 */
	public static void testXmlWrites(final Product product, int numWrites)
			throws Exception {
		// read product into memory
		ByteArrayOutputStream baos = new ByteArrayOutputStream();
		new ObjectProductSource(product)
				.streamTo(new BinaryProductHandler(baos));
		byte[] bytes = baos.toByteArray();

		long time = 0L;

		for (int i = 0; i < numWrites; i++) {
			baos.reset();
			Date start = new Date();

			// parse from memory
			new BinaryProductSource(StreamUtils.getInputStream(bytes))
					.streamTo(new XmlProductHandler(baos));

			Date end = new Date();
			time += end.getTime() - start.getTime();
		}

		System.err.println("xml\tlength=" + baos.toByteArray().length
				+ ",\tnumWrites=" + numWrites + ",\twrite average="
				+ ((double) time / numWrites));
	}

}