001: /*-
002: * See the file LICENSE for redistribution information.
003: *
004: * Copyright (c) 2002,2008 Oracle. All rights reserved.
005: *
006: * $Id: BindingSpeedTest.java,v 1.25.2.2 2008/01/07 15:14:22 cwl Exp $
007: */
008:
009: package com.sleepycat.bind.test;
010:
011: import java.io.Externalizable;
012: import java.io.IOException;
013: import java.io.ObjectInput;
014: import java.io.ObjectInputStream;
015: import java.io.ObjectOutput;
016: import java.io.ObjectOutputStream;
017: import java.io.OutputStreamWriter;
018: import java.io.Serializable;
019: import java.io.Writer;
020: import java.lang.reflect.Field;
021: import java.lang.reflect.Method;
022:
023: import javax.xml.parsers.SAXParserFactory;
024:
025: import junit.framework.Test;
026: import junit.framework.TestCase;
027: import junit.framework.TestSuite;
028:
029: import org.xml.sax.InputSource;
030: import org.xml.sax.XMLReader;
031:
032: import com.sleepycat.bind.serial.SerialInput;
033: import com.sleepycat.bind.serial.SerialOutput;
034: import com.sleepycat.bind.serial.test.TestClassCatalog;
035: import com.sleepycat.bind.tuple.TupleInput;
036: import com.sleepycat.bind.tuple.TupleOutput;
037: import com.sleepycat.collections.test.DbTestUtil;
038: import com.sleepycat.util.FastInputStream;
039: import com.sleepycat.util.FastOutputStream;
040:
041: /**
042: * @author Mark Hayes
043: */
044: public class BindingSpeedTest extends TestCase {
045:
046: static final String JAVA_UNSHARED = "java-unshared".intern();
047: static final String JAVA_SHARED = "java-shared".intern();
048: static final String JAVA_EXTERNALIZABLE = "java-externalizable"
049: .intern();
050: static final String XML_SAX = "xml-sax".intern();
051: static final String TUPLE = "tuple".intern();
052: static final String REFLECT_METHOD = "reflectMethod".intern();
053: static final String REFLECT_FIELD = "reflectField".intern();
054:
055: static final int RUN_COUNT = 1000;
056: static final boolean VERBOSE = false;
057:
058: public static void main(String[] args) throws Exception {
059:
060: junit.framework.TestResult tr = junit.textui.TestRunner
061: .run(suite());
062: if (tr.errorCount() > 0 || tr.failureCount() > 0) {
063: System.exit(1);
064: } else {
065: System.exit(0);
066: }
067: }
068:
069: public static Test suite() {
070:
071: TestSuite suite = new TestSuite();
072: suite.addTest(new BindingSpeedTest(JAVA_UNSHARED));
073: suite.addTest(new BindingSpeedTest(JAVA_SHARED));
074: suite.addTest(new BindingSpeedTest(JAVA_EXTERNALIZABLE));
075: suite.addTest(new BindingSpeedTest(XML_SAX));
076: suite.addTest(new BindingSpeedTest(TUPLE));
077: suite.addTest(new BindingSpeedTest(REFLECT_METHOD));
078: suite.addTest(new BindingSpeedTest(REFLECT_FIELD));
079: return suite;
080: }
081:
082: private String command;
083: private FastOutputStream fo;
084: private TupleOutput to;
085: private TestClassCatalog jtc;
086: private byte[] buf;
087: private XMLReader parser;
088: private Method[] getters;
089: private Method[] setters;
090: private Field[] fields;
091:
092: public BindingSpeedTest(String name) {
093:
094: super ("BindingSpeedTest." + name);
095: command = name;
096: }
097:
098: public void runTest() throws Exception {
099:
100: DbTestUtil.printTestName(getName());
101:
102: boolean isTuple = false;
103: boolean isReflectMethod = false;
104: boolean isReflectField = false;
105: boolean isXmlSax = false;
106: boolean isSerial = false;
107: boolean isShared = false;
108: boolean isExternalizable = false;
109:
110: if (command == TUPLE) {
111: isTuple = true;
112: } else if (command == REFLECT_METHOD) {
113: isReflectMethod = true;
114: } else if (command == REFLECT_FIELD) {
115: isReflectField = true;
116: } else if (command == XML_SAX) {
117: isXmlSax = true;
118: } else if (command == JAVA_UNSHARED) {
119: isSerial = true;
120: } else if (command == JAVA_SHARED) {
121: isSerial = true;
122: isShared = true;
123: } else if (command == JAVA_EXTERNALIZABLE) {
124: isSerial = true;
125: isShared = true;
126: isExternalizable = true;
127: } else {
128: throw new Exception("invalid command: " + command);
129: }
130:
131: // Do initialization
132:
133: if (isTuple) {
134: initTuple();
135: } else if (isReflectMethod) {
136: initReflectMethod();
137: } else if (isReflectField) {
138: initReflectField();
139: } else if (isXmlSax) {
140: initXmlSax();
141: } else if (isSerial) {
142: if (isShared) {
143: initSerialShared();
144: } else {
145: initSerialUnshared();
146: }
147: }
148:
149: // Prime the Java compiler
150:
151: int size = 0;
152: for (int i = 0; i < RUN_COUNT; i += 1) {
153:
154: if (isTuple) {
155: size = runTuple();
156: } else if (isReflectMethod) {
157: size = runReflectMethod();
158: } else if (isReflectField) {
159: size = runReflectField();
160: } else if (isXmlSax) {
161: size = runXmlSax();
162: } else if (isSerial) {
163: if (isShared) {
164: if (isExternalizable) {
165: size = runSerialExternalizable();
166: } else {
167: size = runSerialShared();
168: }
169: } else {
170: size = runSerialUnshared();
171: }
172: }
173: }
174:
175: // Then run the timing tests
176:
177: long startTime = System.currentTimeMillis();
178:
179: for (int i = 0; i < RUN_COUNT; i += 1) {
180: if (isTuple) {
181: size = runTuple();
182: } else if (isReflectMethod) {
183: size = runReflectMethod();
184: } else if (isReflectField) {
185: size = runReflectField();
186: } else if (isXmlSax) {
187: size = runXmlSax();
188: } else if (isSerial) {
189: if (isShared) {
190: if (isExternalizable) {
191: size = runSerialExternalizable();
192: } else {
193: size = runSerialShared();
194: }
195: } else {
196: size = runSerialUnshared();
197: }
198: }
199: }
200:
201: long stopTime = System.currentTimeMillis();
202:
203: assertTrue("data size too big", size < 250);
204:
205: if (VERBOSE) {
206: System.out.println(command);
207: System.out.println("data size: " + size);
208: System.out.println("run time: "
209: + ((stopTime - startTime) / (double) RUN_COUNT));
210: }
211: }
212:
213: public void tearDown() {
214:
215: /* Ensure that GC can cleanup. */
216: command = null;
217: fo = null;
218: to = null;
219: jtc = null;
220: buf = null;
221: parser = null;
222: }
223:
224: void initSerialUnshared() throws Exception {
225:
226: fo = new FastOutputStream();
227: }
228:
229: int runSerialUnshared() throws Exception {
230:
231: fo.reset();
232: ObjectOutputStream oos = new ObjectOutputStream(fo);
233: oos.writeObject(new Data());
234: byte[] bytes = fo.toByteArray();
235: FastInputStream fi = new FastInputStream(bytes);
236: ObjectInputStream ois = new ObjectInputStream(fi);
237: ois.readObject();
238: return bytes.length;
239: }
240:
241: void initSerialShared() throws Exception {
242:
243: jtc = new TestClassCatalog();
244: fo = new FastOutputStream();
245: }
246:
247: int runSerialShared() throws Exception {
248:
249: fo.reset();
250: SerialOutput oos = new SerialOutput(fo, jtc);
251: oos.writeObject(new Data());
252: byte[] bytes = fo.toByteArray();
253: FastInputStream fi = new FastInputStream(bytes);
254: SerialInput ois = new SerialInput(fi, jtc);
255: ois.readObject();
256: return (bytes.length - SerialOutput.getStreamHeader().length);
257: }
258:
259: int runSerialExternalizable() throws Exception {
260:
261: fo.reset();
262: SerialOutput oos = new SerialOutput(fo, jtc);
263: oos.writeObject(new Data2());
264: byte[] bytes = fo.toByteArray();
265: FastInputStream fi = new FastInputStream(bytes);
266: SerialInput ois = new SerialInput(fi, jtc);
267: ois.readObject();
268: return (bytes.length - SerialOutput.getStreamHeader().length);
269: }
270:
271: void initTuple() throws Exception {
272:
273: buf = new byte[500];
274: to = new TupleOutput(buf);
275: }
276:
277: int runTuple() throws Exception {
278:
279: to.reset();
280: new Data().writeTuple(to);
281:
282: TupleInput ti = new TupleInput(to.getBufferBytes(), to
283: .getBufferOffset(), to.getBufferLength());
284: new Data().readTuple(ti);
285:
286: return to.getBufferLength();
287: }
288:
289: void initReflectMethod() throws Exception {
290:
291: initTuple();
292:
293: Class cls = Data.class;
294:
295: getters = new Method[5];
296: getters[0] = cls.getMethod("getField1", new Class[0]);
297: getters[1] = cls.getMethod("getField2", new Class[0]);
298: getters[2] = cls.getMethod("getField3", new Class[0]);
299: getters[3] = cls.getMethod("getField4", new Class[0]);
300: getters[4] = cls.getMethod("getField5", new Class[0]);
301:
302: setters = new Method[5];
303: setters[0] = cls.getMethod("setField1",
304: new Class[] { String.class });
305: setters[1] = cls.getMethod("setField2",
306: new Class[] { String.class });
307: setters[2] = cls.getMethod("setField3",
308: new Class[] { Integer.TYPE });
309: setters[3] = cls.getMethod("setField4",
310: new Class[] { Integer.TYPE });
311: setters[4] = cls.getMethod("setField5",
312: new Class[] { String.class });
313: }
314:
315: int runReflectMethod() throws Exception {
316:
317: to.reset();
318: Data data = new Data();
319: to.writeString((String) getters[0]
320: .invoke(data, (Object[]) null));
321: to.writeString((String) getters[1]
322: .invoke(data, (Object[]) null));
323: to
324: .writeInt(((Integer) getters[2].invoke(data,
325: (Object[]) null)).intValue());
326: to
327: .writeInt(((Integer) getters[3].invoke(data,
328: (Object[]) null)).intValue());
329: to.writeString((String) getters[4]
330: .invoke(data, (Object[]) null));
331:
332: TupleInput ti = new TupleInput(to.getBufferBytes(), to
333: .getBufferOffset(), to.getBufferLength());
334: data = new Data();
335: setters[0].invoke(data, new Object[] { ti.readString() });
336: setters[1].invoke(data, new Object[] { ti.readString() });
337: setters[2].invoke(data,
338: new Object[] { new Integer(ti.readInt()) });
339: setters[3].invoke(data,
340: new Object[] { new Integer(ti.readInt()) });
341: setters[4].invoke(data, new Object[] { ti.readString() });
342:
343: return to.getBufferLength();
344: }
345:
346: void initReflectField() throws Exception {
347:
348: initTuple();
349:
350: Class cls = Data.class;
351:
352: fields = new Field[5];
353: fields[0] = cls.getField("field1");
354: fields[1] = cls.getField("field2");
355: fields[2] = cls.getField("field3");
356: fields[3] = cls.getField("field4");
357: fields[4] = cls.getField("field5");
358: }
359:
360: int runReflectField() throws Exception {
361:
362: to.reset();
363: Data data = new Data();
364: to.writeString((String) fields[0].get(data));
365: to.writeString((String) fields[1].get(data));
366: to.writeInt(((Integer) fields[2].get(data)).intValue());
367: to.writeInt(((Integer) fields[3].get(data)).intValue());
368: to.writeString((String) fields[4].get(data));
369:
370: TupleInput ti = new TupleInput(to.getBufferBytes(), to
371: .getBufferOffset(), to.getBufferLength());
372: data = new Data();
373: fields[0].set(data, ti.readString());
374: fields[1].set(data, ti.readString());
375: fields[2].set(data, new Integer(ti.readInt()));
376: fields[3].set(data, new Integer(ti.readInt()));
377: fields[4].set(data, ti.readString());
378:
379: return to.getBufferLength();
380: }
381:
382: void initXmlSax() throws Exception {
383:
384: buf = new byte[500];
385: fo = new FastOutputStream();
386: SAXParserFactory saxFactory = SAXParserFactory.newInstance();
387: saxFactory.setNamespaceAware(true);
388: parser = saxFactory.newSAXParser().getXMLReader();
389: }
390:
391: int runXmlSax() throws Exception {
392:
393: fo.reset();
394: OutputStreamWriter writer = new OutputStreamWriter(fo);
395: new Data().writeXmlText(writer);
396:
397: byte[] bytes = fo.toByteArray();
398: FastInputStream fi = new FastInputStream(bytes);
399: InputSource input = new InputSource(fi);
400: parser.parse(input);
401:
402: //InputStreamReader reader = new InputStreamReader(fi);
403: //new Data().readXmlText(??);
404:
405: return bytes.length;
406: }
407:
408: static class Data2 extends Data implements Externalizable {
409:
410: public Data2() {
411: }
412:
413: public void readExternal(ObjectInput in) throws IOException,
414: ClassNotFoundException {
415:
416: field1 = in.readUTF();
417: field2 = in.readUTF();
418: field3 = in.readInt();
419: field4 = in.readInt();
420: field5 = in.readUTF();
421: }
422:
423: public void writeExternal(ObjectOutput out) throws IOException {
424:
425: out.writeUTF(field1);
426: out.writeUTF(field2);
427: out.writeInt(field3);
428: out.writeInt(field4);
429: out.writeUTF(field5);
430: }
431: }
432:
433: static class Data implements Serializable {
434:
435: public String field1 = "field1";
436: public String field2 = "field2";
437: public int field3 = 333;
438: public int field4 = 444;
439: public String field5 = "field5";
440:
441: public String getField1() {
442: return field1;
443: }
444:
445: public String getField2() {
446: return field2;
447: }
448:
449: public int getField3() {
450: return field3;
451: }
452:
453: public int getField4() {
454: return field4;
455: }
456:
457: public String getField5() {
458: return field5;
459: }
460:
461: public void setField1(String v) {
462: field1 = v;
463: }
464:
465: public void setField2(String v) {
466: field2 = v;
467: }
468:
469: public void setField3(int v) {
470: field3 = v;
471: }
472:
473: public void setField4(int v) {
474: field4 = v;
475: }
476:
477: public void setField5(String v) {
478: field5 = v;
479: }
480:
481: void readTuple(TupleInput _input) {
482:
483: field1 = _input.readString();
484: field2 = _input.readString();
485: field3 = _input.readInt();
486: field4 = _input.readInt();
487: field5 = _input.readString();
488: }
489:
490: void writeTuple(TupleOutput _output) {
491:
492: _output.writeString(field1);
493: _output.writeString(field2);
494: _output.writeInt(field3);
495: _output.writeInt(field4);
496: _output.writeString(field5);
497: }
498:
499: void writeXmlText(Writer writer) throws IOException {
500:
501: writer.write("<Data><Field1>");
502: writer.write(field1);
503: writer.write("</Field1><Field2>");
504: writer.write(field2);
505: writer.write("</Field2><Field3>");
506: writer.write(String.valueOf(field3));
507: writer.write("</Field3><Field4>");
508: writer.write(String.valueOf(field4));
509: writer.write("</Field4><Field5>");
510: writer.write(field5);
511: writer.write("</Field5></Data>");
512: writer.flush();
513: }
514: }
515: }
|