Home | History | Annotate | Download | only in test
      1 /*
      2  *  PerformanceTest.java
      3  *  Copyright (C) 2007 Amin Ahmad.
      4  *
      5  *  This file is part of Java Ropes.
      6  *
      7  *  Java Ropes is free software: you can redistribute it and/or modify
      8  *  it under the terms of the GNU General Public License as published by
      9  *  the Free Software Foundation, either version 3 of the License, or
     10  *  (at your option) any later version.
     11  *
     12  *  Java Ropes is distributed in the hope that it will be useful,
     13  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
     14  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     15  *  GNU General Public License for more details.
     16  *
     17  *  You should have received a copy of the GNU General Public License
     18  *  along with Java Ropes.  If not, see <http://www.gnu.org/licenses/>.
     19  *
     20  *  Amin Ahmad can be contacted at amin.ahmad (at) gmail.com or on the web at
     21  *  www.ahmadsoft.org.
     22  */
     23 package org.ahmadsoft.ropes.test;
     24 
     25 import java.io.BufferedReader;
     26 import java.io.CharArrayWriter;
     27 import java.io.FileReader;
     28 import java.io.IOException;
     29 import java.io.PrintStream;
     30 import java.io.StringWriter;
     31 import java.io.Writer;
     32 import java.util.Arrays;
     33 import java.util.Random;
     34 import java.util.regex.Matcher;
     35 import java.util.regex.Pattern;
     36 
     37 import org.ahmadsoft.ropes.Rope;
     38 import org.ahmadsoft.ropes.impl.AbstractRope;
     39 
     40 /**
     41  * Performs an extensive performance test comparing Ropes, Strings, and
     42  * StringBuffers.
     43  * @author aahmad
     44  */
     45 public class PerformanceTest {
     46 
     47 	private static int seed=342342;
     48 	private static Random random = new Random(PerformanceTest.seed);
     49 	private static int lenCC = 182029;
     50 	private static int lenBF = 467196;
     51 
     52 	private static final int ITERATION_COUNT = 7;
     53 	private static final int PLAN_LENGTH = 500;
     54 
     55 
     56 	private static String complexString=null;
     57 	private static StringBuffer complexStringBuffer=null;
     58 	private static Rope complexRope=null;
     59 
     60 	/**
     61 	 * @param args
     62 	 */
     63 	public static void main(final String[] args) throws Exception {
     64 
     65 		if (args.length == 1) {
     66 			seed = Integer.parseInt(args[0]);
     67 		}
     68 
     69 		long x,y;
     70 
     71 		x=System.nanoTime();
     72 		final char[] aChristmasCarol_RAW = PerformanceTest.readCC();
     73 		final char[] bensAuto_RAW        = PerformanceTest.readBF();
     74 		final String aChristmasCarol = new String(aChristmasCarol_RAW);
     75 		final String bensAuto        = new String(bensAuto_RAW);
     76 		y=System.nanoTime();
     77 		System.out.println("Read " + aChristmasCarol.length() + " bytes in " + PerformanceTest.time(x,y));
     78 
     79 		System.out.println();
     80 		System.out.println("**** DELETE PLAN TEST ****");
     81 		System.out.println();
     82 
     83 		int newSize = PerformanceTest.lenCC;
     84 		final int[][] deletePlan=new int[PLAN_LENGTH][2];
     85 		for (int j=0;j<deletePlan.length;++j) {
     86 			deletePlan[j][0] = PerformanceTest.random.nextInt(newSize);
     87 			deletePlan[j][1] = PerformanceTest.random.nextInt(Math.min(100, newSize - deletePlan[j][0]));
     88 			newSize -= deletePlan[j][1];
     89 		}
     90 
     91 		for (int k=20; k<=deletePlan.length; k+=20) {
     92 		System.out.println("Delete plan length: " + k);
     93 		{
     94 		long[] stats0 = new long[ITERATION_COUNT], stats1 = new long[ITERATION_COUNT], stats2 = new long[ITERATION_COUNT];
     95 		for (int j=0;j<ITERATION_COUNT;++j){
     96 		stats0[j] = PerformanceTest.stringDeleteTest(aChristmasCarol, deletePlan);
     97 		stats1[j] = PerformanceTest.stringBufferDeleteTest(aChristmasCarol, deletePlan);
     98 		stats2[j] = PerformanceTest.ropeDeleteTest(aChristmasCarol, deletePlan);
     99 		}
    100 		stat(System.out, stats0, "ns", "[String]");
    101 		stat(System.out, stats1, "ns", "[StringBuffer]");
    102 		stat(System.out, stats2, "ns", "[Rope]");
    103 		}
    104 		}
    105 
    106 		System.out.println();
    107 		System.out.println("**** PREPEND PLAN TEST ****");
    108 		System.out.println();
    109 
    110 		final int[][] prependPlan=new int[PLAN_LENGTH][2];
    111 		for (int j=0;j<prependPlan.length;++j) {
    112 			prependPlan[j][0] = PerformanceTest.random.nextInt(PerformanceTest.lenCC);
    113 			prependPlan[j][1] = PerformanceTest.random.nextInt(PerformanceTest.lenCC - prependPlan[j][0]);
    114 		}
    115 
    116 		for (int k=20; k<=prependPlan.length; k+=20) {
    117 		System.out.println("Prepend plan length: " + k);
    118 		{
    119 		long[] stats0 = new long[ITERATION_COUNT], stats1 = new long[ITERATION_COUNT], stats2 = new long[ITERATION_COUNT];
    120 		for (int j=0;j<ITERATION_COUNT;++j){
    121 		stats0[j] = PerformanceTest.stringPrependTest(aChristmasCarol, prependPlan, k);
    122 		stats1[j] = PerformanceTest.stringBufferPrependTest(aChristmasCarol, prependPlan, k);
    123 		stats2[j] = PerformanceTest.ropePrependTest(aChristmasCarol, prependPlan, k);
    124 		}
    125 		stat(System.out, stats0, "ns", "[String]");
    126 		stat(System.out, stats1, "ns", "[StringBuffer]");
    127 		stat(System.out, stats2, "ns", "[Rope]");
    128 		}
    129 		}
    130 
    131 		System.out.println();
    132 		System.out.println("**** APPEND PLAN TEST ****");
    133 		System.out.println();
    134 
    135 		final int[][] appendPlan=new int[PLAN_LENGTH][2];
    136 		for (int j=0;j<appendPlan.length;++j) {
    137 			appendPlan[j][0] = PerformanceTest.random.nextInt(PerformanceTest.lenCC);
    138 			appendPlan[j][1] = PerformanceTest.random.nextInt(PerformanceTest.lenCC - appendPlan[j][0]);
    139 		}
    140 
    141 
    142 		for (int k=20; k<=appendPlan.length; k+=20) {
    143 		System.out.println("Append plan length: " + k);
    144 		{
    145 		long[] stats0 = new long[ITERATION_COUNT], stats1 = new long[ITERATION_COUNT], stats2 = new long[ITERATION_COUNT];
    146 		for (int j=0;j<ITERATION_COUNT;++j){
    147 		stats0[j] = PerformanceTest.stringAppendTest(aChristmasCarol, appendPlan, k);
    148 		stats1[j] = PerformanceTest.stringBufferAppendTest(aChristmasCarol, appendPlan, k);
    149 		stats2[j] = PerformanceTest.ropeAppendTest(aChristmasCarol, appendPlan, k);
    150 		}
    151 		stat(System.out, stats0, "ns", "[String]");
    152 		stat(System.out, stats1, "ns", "[StringBuffer]");
    153 		stat(System.out, stats2, "ns", "[Rope]");
    154 		}
    155 		}
    156 
    157 
    158 		System.out.println();
    159 		System.out.println("**** INSERT PLAN TEST ****");
    160 		System.out.println("* Insert fragments of A Christmas Carol back into itself.\n");
    161 
    162 		final int[][] insertPlan=new int[PLAN_LENGTH][3];
    163 		for (int j=0;j<insertPlan.length;++j) {
    164 			insertPlan[j][0] = PerformanceTest.random.nextInt(PerformanceTest.lenCC);                      //location to insert
    165 			insertPlan[j][1] = PerformanceTest.random.nextInt(PerformanceTest.lenCC);                      //clip from
    166 			insertPlan[j][2] = PerformanceTest.random.nextInt(PerformanceTest.lenCC - insertPlan[j][1]);   //clip length
    167 		}
    168 
    169 
    170 
    171 		for (int k=0; k<=insertPlan.length; k+=20) {
    172 		System.out.println("Insert plan length: " + k);
    173 		{
    174 		long[] stats0 = new long[ITERATION_COUNT], stats1 = new long[ITERATION_COUNT], stats2 = new long[ITERATION_COUNT];
    175 		for (int j=0;j<ITERATION_COUNT;++j){
    176 		stats0[j] = PerformanceTest.stringInsertTest(aChristmasCarol_RAW, insertPlan, k);
    177 		stats1[j] = PerformanceTest.stringBufferInsertTest(aChristmasCarol_RAW, insertPlan, k);
    178 		stats2[j] = PerformanceTest.ropeInsertTest(aChristmasCarol_RAW, insertPlan, k);
    179 		}
    180 		stat(System.out, stats0, "ns", "[String]");
    181 		stat(System.out, stats1, "ns", "[StringBuffer]");
    182 		stat(System.out, stats2, "ns", "[Rope]");
    183 		}
    184 		}
    185 
    186 		System.out.println();
    187 		System.out.println("**** INSERT PLAN TEST 2 ****");
    188 		System.out.println("* Insert fragments of Benjamin Franklin's Autobiography into\n" +
    189 				           "* A Christmas Carol.\n");
    190 
    191 		final int[][] insertPlan2=new int[PLAN_LENGTH][3];
    192 		for (int j=0;j<insertPlan2.length;++j) {
    193 			insertPlan2[j][0] = PerformanceTest.random.nextInt(PerformanceTest.lenCC);                      //location to insert
    194 			insertPlan2[j][1] = PerformanceTest.random.nextInt(PerformanceTest.lenBF);                      //clip from
    195 			insertPlan2[j][2] = PerformanceTest.random.nextInt(PerformanceTest.lenBF - insertPlan2[j][1]);  //clip length
    196 		}
    197 
    198 		{
    199 		long[] stats0 = new long[ITERATION_COUNT], stats1 = new long[ITERATION_COUNT], stats2 = new long[ITERATION_COUNT];
    200 		for (int j=0;j<ITERATION_COUNT;++j){
    201 		stats0[j] = PerformanceTest.stringInsertTest2(aChristmasCarol, bensAuto, insertPlan2);
    202 		stats1[j] = PerformanceTest.stringBufferInsertTest2(aChristmasCarol, bensAuto, insertPlan2);
    203 		stats2[j] = PerformanceTest.ropeInsertTest2(aChristmasCarol, bensAuto, insertPlan2);
    204 		}
    205 		stat(System.out, stats0, "ns", "[String]");
    206 		stat(System.out, stats1, "ns", "[StringBuffer]");
    207 		stat(System.out, stats2, "ns", "[Rope]");
    208 		}
    209 
    210 		System.out.println();
    211 		System.out.println("**** TRAVERSAL TEST 1 (SIMPLY-CONSTRUCTED DATASTRUCTURES) ****");
    212 		System.out.println("* A traversal test wherein the datastructures are simply\n" +
    213 				           "* constructed, meaning constructed straight from the data\n" +
    214 				           "* file with no further modifications. In this case, we expect\n" +
    215 				           "* rope performance to be competitive, with the charAt version\n" +
    216 				           "* performing better than the iterator version.");
    217 		System.out.println();
    218 
    219 		{
    220 		long[] stats0 = new long[ITERATION_COUNT], stats1 = new long[ITERATION_COUNT], stats2 = new long[ITERATION_COUNT], stats3 = new long[ITERATION_COUNT];
    221 		for (int j=0;j<ITERATION_COUNT;++j){
    222 		stats0[j] = PerformanceTest.stringTraverseTest(aChristmasCarol_RAW);
    223 		stats1[j] = PerformanceTest.stringBufferTraverseTest(aChristmasCarol_RAW);
    224 		stats2[j] = PerformanceTest.ropeTraverseTest_1(aChristmasCarol_RAW);
    225 		stats3[j] = PerformanceTest.ropeTraverseTest_2(aChristmasCarol_RAW);
    226 		}
    227 		stat(System.out, stats0, "ns", "[String]");
    228 		stat(System.out, stats1, "ns", "[StringBuffer]");
    229 		stat(System.out, stats2, "ns", "[Rope/charAt]");
    230 		stat(System.out, stats3, "ns", "[Rope/itr]");
    231 		}
    232 
    233 		System.out.println();
    234 		System.out.println("**** TRAVERSAL TEST 2 (COMPLEXLY-CONSTRUCTED DATASTRUCTURES) ****");
    235 		System.out.println("* A traversal test wherein the datastructures are complexly\n" +
    236 				           "* constructed, meaning constructed through hundreds of insertions,\n" +
    237 				           "* substrings, and deletions (deletions not yet implemented). In\n" +
    238 				           "* this case, we expect rope performance to suffer, with the\n" +
    239 				           "* iterator version performing better than the charAt version.");
    240 		System.out.println();
    241 
    242 		{
    243 		long[] stats0 = new long[ITERATION_COUNT], stats1 = new long[ITERATION_COUNT], stats2 = new long[ITERATION_COUNT], stats3 = new long[ITERATION_COUNT];
    244 		for (int j=0;j<ITERATION_COUNT;++j){
    245 		stats0[j] = PerformanceTest.stringTraverseTest2(complexString);
    246 		stats1[j] = PerformanceTest.stringBufferTraverseTest2(complexStringBuffer);
    247 		stats2[j] = PerformanceTest.ropeTraverseTest2_1(complexRope);
    248 		stats3[j] = PerformanceTest.ropeTraverseTest2_2(complexRope);
    249 		}
    250 		stat(System.out, stats0, "ns", "[String]");
    251 		stat(System.out, stats1, "ns", "[StringBuffer]");
    252 		stat(System.out, stats2, "ns", "[Rope/charAt]");
    253 		stat(System.out, stats3, "ns", "[Rope/itr]");
    254 		}
    255 
    256 		System.out.println();
    257 		System.out.println("**** REGULAR EXPRESSION TEST (SIMPLY-CONSTRUCTED DATASTRUCTURES) ****");
    258 		System.out.println("* Using a simply-constructed rope and the pattern 'Crachit'.");
    259 
    260 		Pattern p1 = Pattern.compile("Cratchit");
    261 
    262 		{
    263 		long[] stats0 = new long[ITERATION_COUNT], stats1 = new long[ITERATION_COUNT], stats2 = new long[ITERATION_COUNT], stats3 = new long[ITERATION_COUNT];
    264 		for (int j=0;j<ITERATION_COUNT;++j){
    265 		stats0[j] = PerformanceTest.stringRegexpTest(aChristmasCarol_RAW, p1);
    266 		stats1[j] = PerformanceTest.stringBufferRegexpTest(aChristmasCarol_RAW, p1);
    267 		stats2[j] = PerformanceTest.ropeRegexpTest(aChristmasCarol_RAW, p1);
    268 		stats3[j] = PerformanceTest.ropeMatcherRegexpTest(aChristmasCarol_RAW, p1);
    269 		}
    270 		stat(System.out, stats0, "ns", "[String]");
    271 		stat(System.out, stats1, "ns", "[StringBuffer]");
    272 		stat(System.out, stats2, "ns", "[Rope]");
    273 		stat(System.out, stats3, "ns", "[Rope.matcher]");
    274 		}
    275 
    276 		System.out.println();
    277 		System.out.println("**** REGULAR EXPRESSION TEST (SIMPLY-CONSTRUCTED DATASTRUCTURES) ****");
    278 		System.out.println("* Using a simply-constructed rope and the pattern 'plea.*y'.");
    279 
    280 		p1 = Pattern.compile("plea.*y");
    281 		{
    282 		long[] stats0 = new long[ITERATION_COUNT], stats1 = new long[ITERATION_COUNT], stats2 = new long[ITERATION_COUNT], stats3 = new long[ITERATION_COUNT];
    283 		for (int j=0;j<ITERATION_COUNT;++j){
    284 		stats0[j] = PerformanceTest.stringRegexpTest(aChristmasCarol_RAW, p1);
    285 		stats1[j] = PerformanceTest.stringBufferRegexpTest(aChristmasCarol_RAW, p1);
    286 		stats2[j] = PerformanceTest.ropeRegexpTest(aChristmasCarol_RAW, p1);
    287 		stats3[j] = PerformanceTest.ropeMatcherRegexpTest(aChristmasCarol_RAW, p1);
    288 		}
    289 		stat(System.out, stats0, "ns", "[String]");
    290 		stat(System.out, stats1, "ns", "[StringBuffer]");
    291 		stat(System.out, stats2, "ns", "[Rope]");
    292 		stat(System.out, stats3, "ns", "[Rope.matcher]");
    293 		}
    294 
    295 		System.out.println();
    296 		System.out.println("**** REGULAR EXPRESSION TEST (COMPLEXLY-CONSTRUCTED DATASTRUCTURES) ****");
    297 		System.out.println("* Using a complexly-constructed rope and the pattern 'Crachit'.");
    298 
    299 		p1 = Pattern.compile("Cratchit");
    300 		{
    301 		long[] stats0 = new long[ITERATION_COUNT], stats1 = new long[ITERATION_COUNT], stats2 = new long[ITERATION_COUNT], stats3 = new long[ITERATION_COUNT], stats4 = new long[ITERATION_COUNT];
    302 		for (int j=0;j<ITERATION_COUNT;++j){
    303 		stats0[j] = PerformanceTest.stringRegexpTest2(complexString, p1);
    304 		stats1[j] = PerformanceTest.stringBufferRegexpTest2(complexStringBuffer, p1);
    305 		stats2[j] = PerformanceTest.ropeRegexpTest2(complexRope, p1);
    306 		stats3[j] = PerformanceTest.ropeRebalancedRegexpTest2(complexRope, p1);
    307 		stats4[j] = PerformanceTest.ropeMatcherRegexpTest2(complexRope, p1);
    308 		}
    309 		stat(System.out, stats0, "ns", "[String]");
    310 		stat(System.out, stats1, "ns", "[StringBuffer]");
    311 		stat(System.out, stats2, "ns", "[Rope]");
    312 		stat(System.out, stats3, "ns", "[Reblncd Rope]");
    313 		stat(System.out, stats4, "ns", "[Rope.matcher]");
    314 		}
    315 
    316 		System.out.println();
    317 		System.out.println("**** STRING SEARCH TEST ****");
    318 		System.out.println("* Using a simply constructed rope and the pattern 'Bob was very\n" +
    319 						   "* cheerful with them, and spoke pleasantly to'.");
    320 
    321 		String toFind = "consumes faster than Labor wears; while the used key is always bright,";
    322 		{
    323 		long[] stats0 = new long[ITERATION_COUNT], stats1 = new long[ITERATION_COUNT], stats2 = new long[ITERATION_COUNT];
    324 		for (int j=0;j<ITERATION_COUNT;++j){
    325 		stats0[j] = PerformanceTest.stringFindTest(bensAuto_RAW, toFind);
    326 		stats1[j] = PerformanceTest.stringBufferFindTest(bensAuto_RAW, toFind);
    327 		stats2[j] = PerformanceTest.ropeFindTest(bensAuto_RAW, toFind);
    328 		}
    329 		stat(System.out, stats0, "ns", "[String]");
    330 		stat(System.out, stats1, "ns", "[StringBuffer]");
    331 		stat(System.out, stats2, "ns", "[Rope]");
    332 		}
    333 
    334 		System.out.println();
    335 		System.out.println("**** STRING SEARCH TEST (COMPLEXLY-CONSTRUCTED DATASTRUCTURES)****");
    336 		System.out.println("* Using a complexly constructed rope and the pattern 'consumes faster\n" +
    337 						   "* than Labor wears; while the used key is always bright,'.");
    338 
    339 		toFind = "Bob was very cheerful with them, and spoke pleasantly to";
    340 		{
    341 		long[] stats0 = new long[ITERATION_COUNT], stats1 = new long[ITERATION_COUNT], stats2 = new long[ITERATION_COUNT];
    342 		for (int j=0;j<ITERATION_COUNT;++j){
    343 		stats0[j] = PerformanceTest.stringFindTest2(complexString, toFind);
    344 		stats1[j] = PerformanceTest.stringBufferFindTest2(complexStringBuffer, toFind);
    345 		stats2[j] = PerformanceTest.ropeFindTest2(complexRope, toFind);
    346 		}
    347 		stat(System.out, stats0, "ns", "[String]");
    348 		stat(System.out, stats1, "ns", "[StringBuffer]");
    349 		stat(System.out, stats2, "ns", "[Rope]");
    350 		}
    351 
    352 
    353 		System.out.println();
    354 		System.out.println("**** WRITE TEST ****");
    355 		System.out.println("* Illustrates how to write a Rope to a stream efficiently.");
    356 
    357 		{
    358 		long[] stats0 = new long[ITERATION_COUNT], stats1 = new long[ITERATION_COUNT];
    359 		for (int j=0;j<ITERATION_COUNT;++j){
    360 		stats0[j] = PerformanceTest.ropeWriteBad(complexRope);
    361 		stats1[j] = PerformanceTest.ropeWriteGood(complexRope);
    362 		}
    363 		stat(System.out, stats0, "ns", "[Out.write]");
    364 		stat(System.out, stats1, "ns", "[Rope.write]");
    365 		}
    366 	}
    367 
    368 	private static long stringFindTest(char[] aChristmasCarol, String toFind) {
    369 		long x,y;
    370 
    371 		String b = new String(aChristmasCarol);
    372 		x = System.nanoTime();
    373 		int loc = b.indexOf(toFind);
    374 		y = System.nanoTime();
    375 		System.out.printf("[String.find]       indexOf needle length %d found at index %d in % ,18d ns.\n", toFind.length(), loc, (y-x));
    376 		return (y-x);
    377 	}
    378 
    379 	private static long stringBufferFindTest(char[] aChristmasCarol, String toFind) {
    380 		long x,y;
    381 
    382 		StringBuffer b = new StringBuffer(aChristmasCarol.length); b.append(aChristmasCarol);
    383 		x = System.nanoTime();
    384 		int loc = b.indexOf(toFind);
    385 		y = System.nanoTime();
    386 		System.out.printf("[StringBuffer.find] indexOf needle length %d found at index %d in % ,18d ns.\n", toFind.length(), loc, (y-x));
    387 		return (y-x);
    388 	}
    389 
    390 	private static long ropeFindTest(char[] aChristmasCarol, String toFind) {
    391 		long x,y;
    392 
    393 		Rope b = Rope.BUILDER.build(aChristmasCarol);
    394 		x = System.nanoTime();
    395 		int loc = b.indexOf(toFind);
    396 		y = System.nanoTime();
    397 		System.out.printf("[Rope.find]         indexOf needle length %d found at index %d in % ,18d ns.\n", toFind.length(), loc, (y-x));
    398 		return (y-x);
    399 	}
    400 
    401 	private static long stringFindTest2(String aChristmasCarol, String toFind) {
    402 		long x,y;
    403 
    404 		x = System.nanoTime();
    405 		int loc = aChristmasCarol.indexOf(toFind);
    406 		y = System.nanoTime();
    407 		System.out.printf("[String.find]       indexOf needle length %d found at index %d in % ,18d ns.\n", toFind.length(), loc, (y-x));
    408 		return (y-x);
    409 	}
    410 
    411 	private static long stringBufferFindTest2(StringBuffer aChristmasCarol, String toFind) {
    412 		long x,y;
    413 
    414 		x = System.nanoTime();
    415 		int loc = aChristmasCarol.indexOf(toFind);
    416 		y = System.nanoTime();
    417 		System.out.printf("[StringBuffer.find] indexOf needle length %d found at index %d in % ,18d ns.\n", toFind.length(), loc, (y-x));
    418 		return (y-x);
    419 	}
    420 
    421 	private static long ropeFindTest2(Rope aChristmasCarol, String toFind) {
    422 		long x,y;
    423 
    424 		x = System.nanoTime();
    425 		int loc = aChristmasCarol.indexOf(toFind);
    426 		y = System.nanoTime();
    427 		System.out.printf("[Rope.find]         indexOf needle length %d found at index %d in % ,18d ns.\n", toFind.length(), loc, (y-x));
    428 		return (y-x);
    429 	}
    430 
    431 	private static long ropeWriteGood(Rope complexRope) {
    432 		long x,y;
    433 
    434 		Writer out = new StringWriter(complexRope.length());
    435 		x = System.nanoTime();
    436 		try {
    437 			complexRope.write(out);
    438 		} catch (IOException e) {
    439 			e.printStackTrace();
    440 		}
    441 		y = System.nanoTime();
    442 		System.out.printf("[Rope.write]   Executed write in % ,18d ns.\n", (y-x));
    443 		return (y-x);
    444 	}
    445 
    446 	private static long ropeWriteBad(Rope complexRope) {
    447 		long x,y;
    448 
    449 		Writer out = new StringWriter(complexRope.length());
    450 		x = System.nanoTime();
    451 		try {
    452 			out.write(complexRope.toString());
    453 		} catch (IOException e) {
    454 			e.printStackTrace();
    455 		}
    456 		y = System.nanoTime();
    457 		System.out.printf("[Out.write]    Executed write in % ,18d ns.\n", (y-x));
    458 		return (y-x);
    459 	}
    460 
    461 	private static char[] readBF() throws Exception {
    462 		final CharArrayWriter out = new CharArrayWriter(467196);
    463 		final BufferedReader in = new BufferedReader(new FileReader("AutobiographyOfBenjaminFranklin_BenjaminFranklin.txt"));
    464 
    465 		final char[] c = new char[256];
    466 		int x = -1;
    467 		while (-1 != (x=in.read(c))) {
    468 			out.write(c, 0, x);
    469 		}
    470 		out.close();
    471 		return out.toCharArray();
    472 	}
    473 
    474 	private static char[] readCC() throws Exception {
    475 		final CharArrayWriter out = new CharArrayWriter(182029);
    476 		final BufferedReader in = new BufferedReader(new FileReader("AChristmasCarol_CharlesDickens.txt"));
    477 
    478 		final char[] c = new char[256];
    479 		int x = -1;
    480 		while (-1 != (x=in.read(c))) {
    481 			out.write(c, 0, x);
    482 		}
    483 		out.close();
    484 		return out.toCharArray();
    485 	}
    486 
    487 	private static long ropeAppendTest(final String aChristmasCarol, final int[][] appendPlan, final int planLength) {
    488 		long x,y;
    489 
    490 		x = System.nanoTime();
    491 		Rope result=Rope.BUILDER.build(aChristmasCarol);
    492 
    493 		for (int j=0; j<planLength; ++j) {
    494 			final int offset = appendPlan[j][0];
    495 			final int length = appendPlan[j][1];
    496 			result = result.append(result.subSequence(offset, offset+length));
    497 		}
    498 		y = System.nanoTime();
    499 		System.out.printf("[Rope]         Executed append plan in % ,18d ns. Result has length: %d. Rope Depth: %d\n", (y-x), result.length(), ((AbstractRope)result).depth());
    500 		return (y-x);
    501 	}
    502 
    503 	private static long ropeDeleteTest(final String aChristmasCarol, final int[][] prependPlan) {
    504 		long x,y;
    505 
    506 		x = System.nanoTime();
    507 		Rope result=Rope.BUILDER.build(aChristmasCarol);
    508 
    509 		for (int j=0; j<prependPlan.length; ++j) {
    510 			final int offset = prependPlan[j][0];
    511 			final int length = prependPlan[j][1];
    512 			result = result.delete(offset, offset + length);
    513 		}
    514 		y = System.nanoTime();
    515 		System.out.printf("[Rope]         Executed delete plan in % ,18d ns. Result has length: %d. Rope Depth: %d\n", (y-x), result.length(), ((AbstractRope)result).depth());
    516 		return (y-x);
    517 	}
    518 
    519 	private static long ropeInsertTest(final char[] aChristmasCarol, final int[][] insertPlan, int planLength) {
    520 		long x,y;
    521 		Rope result=Rope.BUILDER.build(aChristmasCarol);
    522 
    523 		x = System.nanoTime();
    524 
    525 		for (int j=0; j<planLength; ++j) {
    526 			final int into   = insertPlan[j][0];
    527 			final int offset = insertPlan[j][1];
    528 			final int length = insertPlan[j][2];
    529 			result = result.insert(into, result.subSequence(offset, offset+length));
    530 		}
    531 		y = System.nanoTime();
    532 		System.out.printf("[Rope]         Executed insert plan in % ,18d ns. Result has length: %d. Rope Depth: %d\n", (y-x), result.length(), ((AbstractRope)result).depth());
    533 		complexRope = result;
    534 		return (y-x);
    535 	}
    536 
    537 	private static long ropeInsertTest2(final String aChristmasCarol, final String bensAuto, final int[][] insertPlan) {
    538 		long x,y;
    539 
    540 		x = System.nanoTime();
    541 		Rope result=Rope.BUILDER.build(aChristmasCarol);
    542 
    543 		for (int j=0; j<insertPlan.length; ++j) {
    544 			final int into   = insertPlan[j][0];
    545 			final int offset = insertPlan[j][1];
    546 			final int length = insertPlan[j][2];
    547 			result = result.insert(into, bensAuto.subSequence(offset, offset+length));
    548 		}
    549 		y = System.nanoTime();
    550 		System.out.printf("[Rope]         Executed insert plan in % ,18d ns. Result has length: %d. Rope Depth: %d\n", (y-x), result.length(), ((AbstractRope)result).depth());
    551 		return (y-x);
    552 	}
    553 
    554 	private static long ropePrependTest(final String aChristmasCarol, final int[][] prependPlan, int planLength) {
    555 		long x,y;
    556 
    557 		x = System.nanoTime();
    558 		Rope result=Rope.BUILDER.build(aChristmasCarol);
    559 
    560 		for (int j=0; j<planLength; ++j) {
    561 			final int offset = prependPlan[j][0];
    562 			final int length = prependPlan[j][1];
    563 			result = result.subSequence(offset, offset+length).append(result);
    564 		}
    565 		y = System.nanoTime();
    566 		System.out.printf("[Rope]         Executed prepend plan in % ,18d ns. Result has length: %d. Rope Depth: %d\n", (y-x), result.length(), ((AbstractRope)result).depth());
    567 		return (y-x);
    568 	}
    569 
    570 	private static long ropeTraverseTest_1(final char[] aChristmasCarol) {
    571 		long x,y,result=0;
    572 		final Rope r=Rope.BUILDER.build(aChristmasCarol);
    573 
    574 		x = System.nanoTime();
    575 
    576 		for (int j=0; j<r.length(); ++j) result+=r.charAt(j);
    577 
    578 		y = System.nanoTime();
    579 		System.out.printf("[Rope/charAt]  Executed traversal in % ,18d ns. Result checksum: %d\n", (y-x), result);
    580 		return (y-x);
    581 	}
    582 
    583 	private static long ropeTraverseTest_2(final char[] aChristmasCarol) {
    584 		long x,y,result=0;
    585 		final Rope r=Rope.BUILDER.build(aChristmasCarol);
    586 
    587 		x = System.nanoTime();
    588 
    589 		for (final char c: r) result+=c;
    590 
    591 		y = System.nanoTime();
    592 		System.out.printf("[Rope/itr]     Executed traversal in % ,18d ns. Result checksum: %d\n", (y-x), result);
    593 		return (y-x);
    594 	}
    595 
    596 	private static long ropeTraverseTest2_1(Rope aChristmasCarol) {
    597 		long x,y;
    598 
    599 		Rope result=aChristmasCarol;
    600 
    601 		int r=0;
    602 		x = System.nanoTime();
    603 		for (int j=0; j<result.length(); ++j) r+=result.charAt(j);
    604 		y = System.nanoTime();
    605 		System.out.printf("[Rope/charAt]  Executed traversal in % ,18d ns. Result checksum: %d\n", (y-x), r);
    606 		return (y-x);
    607 	}
    608 
    609 	private static long ropeTraverseTest2_2(Rope aChristmasCarol) {
    610 		long x,y;
    611 
    612 		Rope result=aChristmasCarol;
    613 
    614 		int r=0;
    615 		x = System.nanoTime();
    616 		for (final char c: result) r+=c;
    617 		y = System.nanoTime();
    618 		System.out.printf("[Rope/itr]     Executed traversal in % ,18d ns. Result checksum: %d\n", (y-x), r);
    619 		return (y-x);
    620 	}
    621 
    622 	private static long stringAppendTest(final String aChristmasCarol, final int[][] appendPlan, final int planLength) {
    623 		long x,y;
    624 
    625 		x = System.nanoTime();
    626 		String result=aChristmasCarol;
    627 
    628 		for (int j=0; j<planLength; ++j) {
    629 			final int offset = appendPlan[j][0];
    630 			final int length = appendPlan[j][1];
    631 			result = result.concat(result.substring(offset, offset + length));
    632 		}
    633 		y = System.nanoTime();
    634 		System.out.printf("[String]       Executed append plan in % ,18d ns. Result has length: %d\n", (y-x), result.length());
    635 		return (y-x);
    636 	}
    637 
    638 	private static long stringBufferAppendTest(final String aChristmasCarol, final int[][] appendPlan, final int planLength) {
    639 		long x,y;
    640 
    641 		x = System.nanoTime();
    642 		final StringBuffer result=new StringBuffer(aChristmasCarol);
    643 
    644 		for (int j=0; j<planLength; ++j) {
    645 			final int offset = appendPlan[j][0];
    646 			final int length = appendPlan[j][1];
    647 			result.append(result.subSequence(offset, offset+length));
    648 		}
    649 		y = System.nanoTime();
    650 		System.out.printf("[StringBuffer] Executed append plan in % ,18d ns. Result has length: %d\n", (y-x), result.length());
    651 		return (y-x);
    652 	}
    653 
    654 	private static long stringBufferDeleteTest(final String aChristmasCarol, final int[][] prependPlan) {
    655 		long x,y;
    656 
    657 		x = System.nanoTime();
    658 		final StringBuffer result=new StringBuffer(aChristmasCarol);
    659 
    660 		for (int j=0; j<prependPlan.length; ++j) {
    661 			final int offset = prependPlan[j][0];
    662 			final int length = prependPlan[j][1];
    663 			result.delete(offset, offset+length);
    664 		}
    665 		y = System.nanoTime();
    666 		System.out.printf("[StringBuffer] Executed delete plan in % ,18d ns. Result has length: %d\n", (y-x), result.length());
    667 		return (y-x);
    668 	}
    669 
    670 	private static long stringBufferInsertTest(final char[] aChristmasCarol, final int[][] insertPlan, int planLength) {
    671 		long x,y;
    672 		final StringBuffer result=new StringBuffer(aChristmasCarol.length); result.append(aChristmasCarol);
    673 
    674 		x = System.nanoTime();
    675 
    676 		for (int j=0; j<planLength; ++j) {
    677 			final int into   = insertPlan[j][0];
    678 			final int offset = insertPlan[j][1];
    679 			final int length = insertPlan[j][2];
    680 			result.insert(into, result.subSequence(offset, offset+length));
    681 		}
    682 		y = System.nanoTime();
    683 		System.out.printf("[StringBuffer] Executed insert plan in % ,18d ns. Result has length: %d\n", (y-x), result.length());
    684 		complexStringBuffer = result;
    685 		return (y-x);
    686 	}
    687 
    688 	private static long stringBufferInsertTest2(final String aChristmasCarol, final String bensAuto, final int[][] insertPlan) {
    689 		long x,y;
    690 
    691 		x = System.nanoTime();
    692 		final StringBuffer result=new StringBuffer(aChristmasCarol);
    693 
    694 		for (int j=0; j<insertPlan.length; ++j) {
    695 			final int into   = insertPlan[j][0];
    696 			final int offset = insertPlan[j][1];
    697 			final int length = insertPlan[j][2];
    698 			result.insert(into, bensAuto.subSequence(offset, offset+length));
    699 		}
    700 		y = System.nanoTime();
    701 		System.out.printf("[StringBuffer] Executed insert plan in % ,18d ns. Result has length: %d\n", (y-x), result.length());
    702 		return (y-x);
    703 	}
    704 
    705 	private static long stringBufferPrependTest(final String aChristmasCarol, final int[][] prependPlan, int planLength) {
    706 		long x,y;
    707 
    708 		x = System.nanoTime();
    709 		final StringBuffer result=new StringBuffer(aChristmasCarol);
    710 
    711 		for (int j=0; j<planLength; ++j) {
    712 			final int offset = prependPlan[j][0];
    713 			final int length = prependPlan[j][1];
    714 			result.insert(0, result.subSequence(offset, offset+length));
    715 		}
    716 		y = System.nanoTime();
    717 		System.out.printf("[StringBuffer] Executed prepend plan in % ,18d ns. Result has length: %d\n", (y-x), result.length());
    718 		return (y-x);
    719 	}
    720 
    721 	private static long stringBufferTraverseTest(final char[] aChristmasCarol) {
    722 		long x,y,result=0;
    723 		final StringBuffer b=new StringBuffer(aChristmasCarol.length); b.append(aChristmasCarol);
    724 
    725 		x = System.nanoTime();
    726 
    727 		for (int j=0; j<b.length(); ++j) result+=b.charAt(j);
    728 
    729 		y = System.nanoTime();
    730 		System.out.printf("[StringBuffer] Executed traversal in % ,18d ns. Result checksum: %d\n", (y-x), result);
    731 		return (y-x);
    732 
    733 	}
    734 
    735 	private static long stringBufferTraverseTest2(final StringBuffer aChristmasCarol) {
    736 		long x,y;
    737 
    738 		final StringBuffer result=aChristmasCarol;
    739 
    740 		int r=0;
    741 		x = System.nanoTime();
    742 		for (int j=0; j<result.length(); ++j) r+=result.charAt(j);
    743 		y = System.nanoTime();
    744 		System.out.printf("[StringBuffer] Executed traversal in % ,18d ns. Result checksum: %d\n", (y-x), r);
    745 		return (y-x);
    746 	}
    747 
    748 	private static long stringDeleteTest(final String aChristmasCarol, final int[][] prependPlan) {
    749 		long x,y;
    750 
    751 		x = System.nanoTime();
    752 		String result=aChristmasCarol;
    753 
    754 		for (int j=0; j<prependPlan.length; ++j) {
    755 			final int offset = prependPlan[j][0];
    756 			final int length = prependPlan[j][1];
    757 			result = result.substring(0, offset).concat(result.substring(offset+length));
    758 		}
    759 		y = System.nanoTime();
    760 		System.out.printf("[String]       Executed delete plan in % ,18d ns. Result has length: %d\n", (y-x), result.length());
    761 		return (y-x);
    762 	}
    763 
    764 	private static long stringInsertTest(final char[] aChristmasCarol, final int[][] insertPlan, int planLength) {
    765 		long x,y;
    766 		String result=new String(aChristmasCarol);
    767 
    768 		x = System.nanoTime();
    769 
    770 		for (int j=0; j<planLength; ++j) {
    771 			final int into   = insertPlan[j][0];
    772 			final int offset = insertPlan[j][1];
    773 			final int length = insertPlan[j][2];
    774 			result = result.substring(0, into).concat(result.substring(offset, offset + length)).concat(result.substring(into));
    775 
    776 		}
    777 		y = System.nanoTime();
    778 		System.out.printf("[String]       Executed insert plan in % ,18d ns. Result has length: %d\n", (y-x), result.length());
    779 		complexString = result;
    780 		return (y-x);
    781 	}
    782 
    783 	private static long stringInsertTest2(final String aChristmasCarol, final String bensAuto, final int[][] insertPlan) {
    784 		long x,y;
    785 
    786 		x = System.nanoTime();
    787 		String result=aChristmasCarol;
    788 
    789 		for (int j=0; j<insertPlan.length; ++j) {
    790 			final int into   = insertPlan[j][0];
    791 			final int offset = insertPlan[j][1];
    792 			final int length = insertPlan[j][2];
    793 			result = result.substring(0, into).concat(bensAuto.substring(offset, offset + length)).concat(result.substring(into));
    794 		}
    795 		y = System.nanoTime();
    796 		System.out.printf("[String]       Executed insert plan in % ,18d ns. Result has length: %d\n", (y-x), result.length());
    797 		return (y-x);
    798 	}
    799 
    800 	private static long stringPrependTest(final String aChristmasCarol, final int[][] prependPlan, int planLength) {
    801 		long x,y;
    802 
    803 		x = System.nanoTime();
    804 		String result=aChristmasCarol;
    805 
    806 		for (int j=0; j<planLength; ++j) {
    807 			final int offset = prependPlan[j][0];
    808 			final int length = prependPlan[j][1];
    809 			result = result.substring(offset, offset + length).concat(result);
    810 		}
    811 		y = System.nanoTime();
    812 		System.out.printf("[String]       Executed prepend plan in % ,18d ns. Result has length: %d\n", (y-x), result.length());
    813 		return (y-x);
    814 	}
    815 
    816 	private static long stringTraverseTest(final char[] aChristmasCarol) {
    817 		long x,y,result=0;
    818 		String s = new String(aChristmasCarol);
    819 
    820 		x = System.nanoTime();
    821 
    822 		for (int j=0; j<s.length(); ++j) result+=s.charAt(j);
    823 
    824 		y = System.nanoTime();
    825 		System.out.printf("[String]       Executed traversal in % ,18d ns. Result checksum: %d\n", (y-x), result);
    826 		return (y-x);
    827 	}
    828 
    829 	private static long stringTraverseTest2(final String aChristmasCarol) {
    830 		long x,y;
    831 
    832 		String result=aChristmasCarol;
    833 
    834 		int r=0;
    835 		x = System.nanoTime();
    836 		for (int j=0; j<result.length(); ++j) r+=result.charAt(j);
    837 		y = System.nanoTime();
    838 		System.out.printf("[String]       Executed traversal in % ,18d ns. Result checksum: %d\n", (y-x), r);
    839 		return (y-x);
    840 	}
    841 
    842 	private static long stringRegexpTest(final char[] aChristmasCarol, Pattern pattern) {
    843 		long x,y;
    844 		String s = new String(aChristmasCarol);
    845 
    846 		x = System.nanoTime();
    847 
    848 		int result = 0;
    849 		Matcher m = pattern.matcher(s);
    850 		while (m.find()) ++result;
    851 
    852 		y = System.nanoTime();
    853 		System.out.printf("[String]       Executed regexp test in % ,18d ns. Found %d matches.\n", (y-x), result);
    854 		return (y-x);
    855 	}
    856 
    857 	private static long stringBufferRegexpTest(final char[] aChristmasCarol, Pattern pattern) {
    858 		long x,y;
    859 		StringBuffer buffer = new StringBuffer(aChristmasCarol.length); buffer.append(aChristmasCarol);
    860 
    861 		x = System.nanoTime();
    862 
    863 		int result = 0;
    864 		Matcher m = pattern.matcher(buffer);
    865 		while (m.find()) ++result;
    866 
    867 		y = System.nanoTime();
    868 		System.out.printf("[StringBuffer] Executed regexp test in % ,18d ns. Found %d matches.\n", (y-x), result);
    869 		return (y-x);
    870 	}
    871 
    872 	private static long ropeRegexpTest(final char[] aChristmasCarol, Pattern pattern) {
    873 		long x,y;
    874 		Rope rope = Rope.BUILDER.build(aChristmasCarol);
    875 
    876 		x = System.nanoTime();
    877 
    878 		int result = 0;
    879 		Matcher m = pattern.matcher(rope);
    880 		while (m.find()) ++result;
    881 
    882 		y = System.nanoTime();
    883 		System.out.printf("[Rope]         Executed regexp test in % ,18d ns. Found %d matches.\n", (y-x), result);
    884 		return (y-x);
    885 	}
    886 
    887 	private static long ropeMatcherRegexpTest(final char[] aChristmasCarol, Pattern pattern) {
    888 		long x,y;
    889 		Rope rope = Rope.BUILDER.build(aChristmasCarol);
    890 
    891 		x = System.nanoTime();
    892 
    893 		int result = 0;
    894 		Matcher m = rope.matcher(pattern);
    895 		while (m.find()) ++result;
    896 
    897 		y = System.nanoTime();
    898 		System.out.printf("[Rope.matcher] Executed regexp test in % ,18d ns. Found %d matches.\n", (y-x), result);
    899 		return (y-x);
    900 	}
    901 
    902 
    903 
    904 	private static long stringRegexpTest2(final String aChristmasCarol, Pattern pattern) {
    905 		long x,y;
    906 
    907 		x = System.nanoTime();
    908 
    909 		int result = 0;
    910 		Matcher m = pattern.matcher(aChristmasCarol);
    911 		while (m.find()) ++result;
    912 
    913 		y = System.nanoTime();
    914 		System.out.printf("[String]       Executed regexp test in % ,18d ns. Found %d matches.\n", (y-x), result);
    915 		return (y-x);
    916 	}
    917 
    918 	private static long stringBufferRegexpTest2(final StringBuffer aChristmasCarol, Pattern pattern) {
    919 		long x,y;
    920 
    921 		x = System.nanoTime();
    922 
    923 		int result = 0;
    924 		Matcher m = pattern.matcher(aChristmasCarol);
    925 		while (m.find()) ++result;
    926 
    927 		y = System.nanoTime();
    928 		System.out.printf("[StringBuffer] Executed regexp test in % ,18d ns. Found %d matches.\n", (y-x), result);
    929 		return (y-x);
    930 	}
    931 
    932 	private static long ropeRegexpTest2(final Rope aChristmasCarol, Pattern pattern) {
    933 		long x,y;
    934 
    935 		x = System.nanoTime();
    936 
    937 		int result = 0;
    938 		Matcher m = pattern.matcher(aChristmasCarol);
    939 		while (m.find()) ++result;
    940 
    941 		y = System.nanoTime();
    942 		System.out.printf("[Rope]         Executed regexp test in % ,18d ns. Found %d matches.\n", (y-x), result);
    943 		return (y-x);
    944 	}
    945 
    946 	private static long ropeRebalancedRegexpTest2(final Rope aChristmasCarol, Pattern pattern) {
    947 		long x,y;
    948 
    949 		x = System.nanoTime();
    950 
    951 		CharSequence adaptedRope = aChristmasCarol.rebalance(); //Rope.BUILDER.buildForRegexpSearching(aChristmasCarol);
    952 		int result = 0;
    953 		Matcher m = pattern.matcher(adaptedRope);
    954 		while (m.find()) ++result;
    955 
    956 		y = System.nanoTime();
    957 		System.out.printf("[Reblncd Rope] Executed regexp test in % ,18d ns. Found %d matches.\n", (y-x), result);
    958 		return (y-x);
    959 	}
    960 
    961 	private static long ropeMatcherRegexpTest2(final Rope aChristmasCarol, Pattern pattern) {
    962 		long x,y;
    963 
    964 		x = System.nanoTime();
    965 
    966 		int result = 0;
    967 		Matcher m = aChristmasCarol.matcher(pattern);
    968 		while (m.find()) ++result;
    969 
    970 		y = System.nanoTime();
    971 		System.out.printf("[Rope.matcher] Executed regexp test in % ,18d ns. Found %d matches.\n", (y-x), result);
    972 		return (y-x);
    973 	}
    974 
    975 	private static String time(final long x, final long y) {
    976 		return (y-x) + "ns";
    977 	}
    978 
    979 	private static void stat(PrintStream out, long[] stats, String unit, String prefix) {
    980 		if (stats.length < 3)
    981 			System.err.println("Cannot print stats.");
    982 		Arrays.sort(stats);
    983 
    984 		double median = ((stats.length & 1) == 1 ? stats[stats.length >> 1]: (stats[stats.length >> 1] + stats[1 + (stats.length >> 1)]) / 2);
    985 		double average = 0;
    986 		for (int j=1;j<stats.length-1;++j) {
    987 			average += stats[j];
    988 		}
    989 		average /= stats.length - 2;
    990 		out.printf("%-14s Average=% ,16.0f %s Median=% ,16.0f%s\n", prefix, average, unit, median, unit);
    991 	}
    992 
    993 }
    994