blob: d5a372680b9fba2dcaa3dbb714e8178ec0d58d9c [file] [log] [blame]
package perf;
public class ManualCharAccessTest
{
protected int hash;
protected final static byte[] SMALL_BYTE_CODES = new byte[256];
protected final static int[] SMALL_INT_CODES = new int[256];
protected final static int[] INT_CODES = new int[0x10000];
protected final static byte[] BYTE_CODES = new byte[0x10000];
static {
for (int i = 0; i < 32; ++i) {
if (!(i == '\r' || i == '\n' || i == '\t')) {
INT_CODES[i] = 1;
BYTE_CODES[i] = 1;
SMALL_BYTE_CODES[i] = 1;
SMALL_INT_CODES[i] = 1;
}
}
INT_CODES['\\'] = 2;
BYTE_CODES['\\'] = 2;
SMALL_BYTE_CODES['\\'] = 2;
SMALL_INT_CODES['\\'] = 2;
}
protected String generateString(int len)
{
int counter = 0;
StringBuilder sb = new StringBuilder(len + 20);
do {
sb.append("Some stuff: ").append(len).append("\n");
if ((++counter % 31) == 0) {
sb.append("\\");
}
} while (sb.length() < len);
return sb.toString();
}
private void test() throws Exception
{
final String INPUT_STR = generateString(23000);
final char[] INPUT_CHARS = INPUT_STR.toCharArray();
final char[] OUTPUT = new char[INPUT_CHARS.length];
// Let's try to guestimate suitable size, N megs of output
final int REPS = (int) ((double) (80 * 1000 * 1000) / (double) INPUT_CHARS.length);
System.out.printf("%d bytes to scan, will do %d repetitions\n",
INPUT_CHARS.length, REPS);
int i = 0;
int roundsDone = 0;
final int TYPES = 3;
final int WARMUP_ROUNDS = 5;
final long[] times = new long[TYPES];
while (true) {
int round = (i++ % TYPES);
String msg;
boolean lf = (round == 0);
long msecs;
switch (round) {
case 0:
msg = "Read classic";
msecs = readClassic(REPS, INPUT_CHARS, OUTPUT);
break;
case 1:
msg = "Read, byte[]";
msecs = readWithByte(REPS, INPUT_CHARS, OUTPUT);
break;
case 2:
msg = "Read, int[]";
msecs = readWithInt(REPS, INPUT_CHARS, OUTPUT);
break;
default:
throw new Error();
}
// skip first 5 rounds to let results stabilize
if (roundsDone >= WARMUP_ROUNDS) {
times[round] += msecs;
}
System.out.printf("Test '%s' [hash: 0x%s] -> %d msecs\n", msg, this.hash, msecs);
if (lf) {
++roundsDone;
if ((roundsDone % 7) == 0 && roundsDone > WARMUP_ROUNDS) {
double den = (double) (roundsDone - WARMUP_ROUNDS);
System.out.printf("Averages after %d rounds (classic, byte[], int[]): "
+"%.1f / %.1f / %.1f msecs\n",
(int) den
,times[0] / den, times[1] / den, times[2] / den
);
}
System.out.println();
}
if ((i % 17) == 0) {
System.out.println("[GC]");
Thread.sleep(100L);
System.gc();
Thread.sleep(100L);
}
}
}
private final long readClassic(int REPS, char[] input, char[] output) throws Exception
{
long start = System.currentTimeMillis();
final byte[] codes = SMALL_BYTE_CODES;
final int MAX = 256;
while (--REPS >= 0) {
int outPtr = 0;
for (int i = 0, end = input.length; i < end; ++i) {
int ch = input[i];
if (ch < MAX && codes[ch] == NULL_BYTE) {
output[outPtr++] = (char) ch;
continue;
}
if (ch == '\\') {
output[outPtr++] = '_';
} else if (ch == '\n') {
output[outPtr++] = '_';
}
}
}
long time = System.currentTimeMillis() - start;
return time;
}
private final long readWithByte(int REPS, char[] input, char[] output) throws Exception
{
long start = System.currentTimeMillis();
final byte[] codes = BYTE_CODES;
while (--REPS >= 0) {
int outPtr = 0;
for (int i = 0, end = input.length; i < end; ++i) {
char ch = input[i];
if (codes[ch] == NULL_BYTE) {
output[outPtr++] = ch;
continue;
}
if (ch == '\\') {
output[outPtr++] = '_';
} else if (ch == '\n') {
output[outPtr++] = '_';
}
}
}
long time = System.currentTimeMillis() - start;
return time;
}
final static byte NULL_BYTE = (byte) 0;
private final long readWithInt(int REPS, char[] input, char[] output) throws Exception
{
long start = System.currentTimeMillis();
final int[] codes = INT_CODES;
while (--REPS >= 0) {
int outPtr = 0;
for (int i = 0, end = input.length; i < end; ++i) {
char ch = input[i];
if (codes[ch] == 0) {
output[outPtr++] = ch;
continue;
}
if (ch == '\\') {
output[outPtr++] = '_';
} else if (ch == '\n') {
output[outPtr++] = '_';
}
}
}
long time = System.currentTimeMillis() - start;
return time;
}
public static void main(String[] args) throws Exception
{
if (args.length != 0) {
System.err.println("Usage: java ...");
System.exit(1);
}
new ManualCharAccessTest().test();
}
}