001: /*
002: * Javolution - Java(TM) Solution for Real-Time and Embedded Systems
003: * Copyright (C) 2007 - Javolution (http://javolution.org/)
004: * All rights reserved.
005: *
006: * Permission to use, copy, modify, and distribute this software is
007: * freely granted, provided that this notice is preserved.
008: */
009: package javolution;
010:
011: import j2me.lang.CharSequence;
012: import javolution.context.ArrayFactory;
013: import javolution.context.ConcurrentContext;
014: import javolution.context.LocalContext;
015: import javolution.context.ObjectFactory;
016: import javolution.context.StackContext;
017: import javolution.lang.MathLib;
018: import javolution.testing.TestCase;
019: import javolution.testing.TestSuite;
020: import javolution.testing.TestContext;
021: import javolution.text.TextBuilder;
022: import javolution.util.FastTable;
023: import javolution.util.Index;
024:
025: /**
026: * <p> This class holds {@link javolution.context} benchmark.</p>
027: *
028: * @author <a href="mailto:jean-marie@dautelle.com">Jean-Marie Dautelle</a>
029: * @version 5.2, August 19, 2007
030: */
031: public final class ContextTestSuite extends TestSuite {
032:
033: public void run() {
034: TestContext
035: .info("-------------------------------------------------");
036: TestContext
037: .info("-- Test Suite for package javolution.context.* --");
038: TestContext
039: .info("-------------------------------------------------");
040: final int defaultConcurrency = ConcurrentContext
041: .getConcurrency();
042: TestContext.test(new Concurrency(10000, 0));
043: TestContext.test(new Concurrency(10000, defaultConcurrency));
044: TestContext.info("");
045: TestContext.test(new SmallObjectAllocation(1000, false));
046: TestContext.test(new SmallObjectAllocation(1000, true));
047: TestContext.info("");
048: TestContext.test(new ArrayAllocation(4096, false));
049: TestContext.test(new ArrayAllocation(4096, true));
050: TestContext.info("");
051: }
052:
053: public static class Concurrency extends TestCase {
054: final int _size;
055:
056: final int _concurrency;
057:
058: FastTable _table;
059:
060: public Concurrency(int size, int concurrency) {
061: _size = size;
062: _concurrency = concurrency;
063: }
064:
065: public CharSequence getDescription() {
066: return TextBuilder.newInstance().append(
067: "ConcurrentContext - Quick Sort (size: ").append(
068: _size).append(", concurrency: ").append(
069: _concurrency).append(")");
070: }
071:
072: public void prepare() {
073: _table = new FastTable(_size);
074: for (int i = 0; i < _size; i++) {
075: _table.add(Index.valueOf(MathLib.random(0, _size)));
076: }
077: }
078:
079: public void execute() {
080: LocalContext.enter();
081: try {
082: ConcurrentContext.setConcurrency(_concurrency);
083: quickSort(_table);
084: } finally {
085: LocalContext.exit();
086: }
087: }
088:
089: public void validate() {
090: TestContext.assertEquals("Size", new Integer(_size),
091: new Integer(_table.size()));
092: for (int i = 0; i < _size - 1; i++) {
093: int i1 = ((Index) _table.get(i)).intValue();
094: int i2 = ((Index) _table.get(i + 1)).intValue();
095: if (!TestContext.assertTrue("Natural Order", i1 <= i2))
096: break;
097: }
098: }
099:
100: private void quickSort(final FastTable table) {
101: final int size = table.size();
102: if (size < 100) {
103: table.sort();
104: } else {
105: final FastTable t1 = FastTable.newInstance();
106: final FastTable t2 = FastTable.newInstance();
107: ConcurrentContext.enter();
108: try {
109: ConcurrentContext.execute(new Runnable() {
110: public void run() {
111: t1.addAll(table.subList(0, size / 2));
112: quickSort(t1);
113: }
114: });
115: ConcurrentContext.execute(new Runnable() {
116: public void run() {
117: t2.addAll(table.subList(size / 2, size));
118: quickSort(t2);
119: }
120: });
121: } finally {
122: ConcurrentContext.exit();
123: }
124: // Merges results.
125: for (int i = 0, i1 = 0, i2 = 0; i < size; i++) {
126: if (i1 >= t1.size()) {
127: table.set(i, t2.get(i2++));
128: } else if (i2 >= t2.size()) {
129: table.set(i, t1.get(i1++));
130: } else {
131: Index o1 = (Index) t1.get(i1);
132: Index o2 = (Index) t2.get(i2);
133: if (o1.intValue() < o2.intValue()) {
134: table.set(i, o1);
135: i1++;
136: } else {
137: table.set(i, o2);
138: i2++;
139: }
140: }
141: }
142: FastTable.recycle(t1);
143: FastTable.recycle(t2);
144: }
145: }
146: }
147:
148: public static class SmallObjectAllocation extends TestCase {
149: int _size;
150:
151: boolean _useStack;
152:
153: XYZ c0, c1;
154:
155: public SmallObjectAllocation(int size, boolean useStack) {
156: _size = size;
157: _useStack = useStack;
158: }
159:
160: public CharSequence getDescription() {
161: return TextBuilder.newInstance().append(
162: (!_useStack) ? "HeapContext (default) - Create "
163: : "StackContext Create ")
164: .append(_size).append(" small objects");
165: }
166:
167: public void prepare() {
168: c0 = new XYZ(0.0, 0.0, 0.0);
169: c1 = new XYZ(-1.0, 1.0, 0.0);
170: StackContext.enter(); // Allows stack allocations.
171: }
172:
173: public void execute() {
174: if (_useStack) {
175: for (int i = 0; i < _size; i++) { // Fibonacci sequence.
176: XYZ cn = c1.plusStack(c0);
177: c0 = c1;
178: c1 = cn;
179: }
180: } else {
181: for (int i = 0; i < _size; i++) { // Fibonacci sequence.
182: XYZ cn = c1.plusHeap(c0);
183: c0 = c1;
184: c1 = cn;
185: }
186: }
187: }
188:
189: public int count() {
190: return _size;
191: }
192:
193: public void cleanup() {
194: StackContext.exit();
195: }
196:
197: public void validate() {
198: TestContext.assertTrue(c0.x == -c0.y);
199: }
200:
201: private static final class XYZ {
202: static ObjectFactory FACTORY = new ObjectFactory() {
203: protected Object create() {
204: return new XYZ();
205: }
206: };
207:
208: double x, y, z;
209:
210: private XYZ() {
211: }
212:
213: public XYZ(double x, double y, double z) {
214: this .x = x;
215: this .y = y;
216: this .z = z;
217: }
218:
219: public static XYZ valueOf(double x, double y, double z) {
220: XYZ c = (XYZ) FACTORY.object();
221: c.x = x;
222: c.y = y;
223: c.z = z;
224: return c;
225: }
226:
227: public XYZ plusStack(XYZ that) {
228: return XYZ.valueOf(this .x + that.x, this .y + that.y,
229: this .z + that.z);
230: }
231:
232: public XYZ plusHeap(XYZ that) {
233: return new XYZ(this .x + that.x, this .y + that.y, this .z
234: + that.z);
235: }
236: }
237: }
238:
239: public static class ArrayAllocation extends TestCase {
240: int _size;
241:
242: boolean _recycle;
243:
244: char[] _array;
245:
246: public ArrayAllocation(int size, boolean recycle) {
247: _size = size;
248: _recycle = recycle;
249: }
250:
251: public CharSequence getDescription() {
252: if (_recycle) {
253: return TextBuilder.newInstance().append(
254: "Recycled - ArrayFactory.CHARS_FACTORY.array(")
255: .append(_size).append(")");
256: } else {
257: return TextBuilder.newInstance().append(
258: "HeapContext (default) - new char[")
259: .append(_size).append("]");
260: }
261: }
262:
263: public void execute() {
264: if (_recycle) {
265: _array = (char[]) ArrayFactory.CHARS_FACTORY
266: .array(_size);
267: ArrayFactory.CHARS_FACTORY.recycle(_array);
268: } else {
269: _array = new char[_size];
270: }
271: }
272:
273: public void validate() {
274: TestContext.assertTrue(_array.length >= _size);
275: }
276: }
277: }
|