import java.util.Random;
public class Main {
static interface StripAlg {
String strip(String old);
String name();
}
private final static StripAlg strip1 = new StripAlg() {
@Override
public String strip(final String old) {
final int length = old.length();
final char[] oldChars = new char[length];
old.getChars(0, length, oldChars, 0);
int newLen = 0;
for(int j = 0; j < length; j++) {
final char ch = oldChars[j];
if (ch >= ' ') {
oldChars[newLen] = ch;
newLen++;
}
}
return new String(oldChars, 0, newLen);
}
@Override
public String name() {
return "Alg1";
}
};
private final static StripAlg strip2 = new StripAlg() {
@Override
public String strip(final String old) {
final StringBuffer sb = new StringBuffer(old.length());
for(int i = 0; i < old.length(); i++) {
final char ch = old.charAt(i);
if (ch >= ' ') {
sb.append(ch);
}
}
return sb.toString();
}
@Override
public String name() {
return "Alg2";
}
};
private final static StripAlg strip3 = new StripAlg() {
@Override
public String strip(final String old) {
final int length = old.length();
final char[] oldChars = new char[length + 1];
old.getChars(0, length, oldChars, 0);
oldChars[length] = '\0';// avoiding explicit bound check in while
int newLen = -1;
while(oldChars[++newLen] >= ' ')
;// find first non-printable,
// if there are none it ends on the null char I appended
for(int j = newLen; j < length; j++) {
final char ch = oldChars[j];
if (ch >= ' ') {
oldChars[newLen] = ch;// the while avoids repeated
// overwriting here when newLen==j
newLen++;
}
}
return new String(oldChars, 0, newLen);
}
@Override
public String name() {
return "Alg3";
}
};
private static String getTestString(final int size, final int maxCharVal, final long seed) {
final Random rand = new Random(seed);
final StringBuffer sb = new StringBuffer(size);
for(int i = 0; i < size; i++) {
sb.append((char) rand.nextInt(maxCharVal));
}
return sb.toString();
}
private static double testAlg(final StripAlg alg, final String test, final int runs) {
final long start = System.nanoTime();
for(int i = 0; i < runs; i++) {
alg.strip(test);
}
final long end = System.nanoTime();
return (double)(end - start) / 1000000;
}
public static void main(final String[] args) {
final long seed = 0xdeadcafe;
final int size = 200;
final int maxCharVal = 200; // 32/200 ~ percentage of non printables
final String test = getTestString(size, maxCharVal, seed);
final int nrRuns = 10000;
final StripAlg algs[] = { strip1, strip2, strip3 };
for(final StripAlg alg : algs) {
getTime(alg, size, test, nrRuns);
}
}
private static void getTime(final StripAlg alg, final int size, final String test,
final int nrRuns) {
double minRun = Double.MAX_VALUE;
for(int i = 0; i < 1000; i++) {
minRun = Math.min(minRun, testAlg(alg, test, nrRuns));
}
System.out.printf("%s takes %.2fms per %d elements (%.2fops/s)%n", alg.name(), minRun, nrRuns,
(double) nrRuns / minRun * 1000);
}
}