Re: FastCat 'performance'
On 2/27/13 12:58 PM, Joerg Meier wrote:
On Wed, 27 Feb 2013 12:38:11 -0800, Daniel Pitts wrote:
I've made the Strings you append longer, and I've fixed the estimates
for the FastCat and the StringBu*ers constructors to be spot-on:
Fresh SB/FCs:
Cat> Init: 00.000ms, Loop: 00.175ms, End: 00.000ms, Total: 00.175ms.
Buf> Init: 00.000ms, Loop: 00.227ms, End: 00.000ms, Total: 00.227ms.
Bui> Init: 00.000ms, Loop: 00.236ms, End: 00.000ms, Total: 00.236ms.
Reused SB/FCs:
Cat> Init: 00.000ms, Loop: 00.023ms, End: 00.375ms, Total: 00.398ms.
Buf> Init: 00.101ms, Loop: 00.048ms, End: 00.130ms, Total: 00.279ms.
Bui> Init: 00.092ms, Loop: 00.052ms, End: 00.130ms, Total: 00.274ms.
I'm curious, would you mind sharing the updated code on a pastebin
somewhere ? Writing benchmarks is always tricky, so I'd be happy to learn
from your changes.
Liebe Gruesse,
Joerg
Here it is in all its glory:
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import com.mindprod.fastcat.FastCat;
class CatTester {
public static final String LONG_STRING =
"abcdefgabcdefgabcdefgabcdefgabc" +
"defgabcdefgabcdefgabcdefgabcdefgabcde" +
"defgabcdefgabcdefgabcdefgabcdefgabcde" +
"defgabcdefgabcdefgabcdefgabcdefgabcde" +
"defgabcdefgabcdefgabcdefgabcdefgabcde" +
"defgabcdefgabcdefgabcdefgabcdefgabcde" +
"defgabcdefgabcdefgabcdefgabcdefgabcde" +
"defgabcdefgabcdefgabcdefgabcdefgabcde" +
"defgabcdefgabcdefgabcdefgabcdefgabcde" +
"fg"
;
public static final String ANOTHER_STRING = "xvck" +
"blahblahblahblahxjcvh" +
"blahblahblahblahxjcvh" +
"blahblahblahblahxjcvh" +
"blahblahblahblahxjcvh" +
"blahblahblahblahxjcvh" +
"blahblahblahblahxjcvh" +
"blahblahblahblahxjcvh" +
"blahblahblahblahxjcvh" +
"blahblahblahblahxjcvh" +
"blahblahblahblahxjcvh" +
"blahblahblahblahxjcvh" +
"blahblahblahblahxjcvh" +
"blahblahblahblahxjcvh" +
"blahblahblahblahxjcvh" +
"blahblahblahblahxjcvh" +
"blahblahblahblahxjcvh" +
"blahblahblahblahxjcvh" +
"blahblahblahblahxjcvh" +
"blahblahblahblahxjcvh" +
"";
private interface Tester {
public void init();
public int test(final long junk);
String conclude();
}
private static class TestFastCat implements Tester {
protected FastCat sb;
public TestFastCat() {
}
public void init() {
}
public String conclude() {
if (sb != null) {
return sb.toString();
}
return null;
}
public int test(final long junk) {
final FastCat sbLocal = sb == null ? new FastCat(6) : sb;
final int start = sbLocal.length();
sbLocal.append(LONG_STRING);
sbLocal.append(1234);
sbLocal.append(ANOTHER_STRING);
sbLocal.append(junk);
sbLocal.append(ANOTHER_STRING);
sbLocal.append(junk + 1);
if (sbLocal != sb) {
sbLocal.toString();
}
return sbLocal.length() - start;
}
}
private static class TestStringBuffer implements Tester {
protected StringBuffer sb;
public TestStringBuffer() {
}
public void init() {
}
public int test(final long junk) {
final StringBuffer sbLocal = sb == null ? new StringBuffer() : sb;
final int start = sbLocal.length();
sbLocal.append(LONG_STRING);
sbLocal.append(1234);
sbLocal.append(ANOTHER_STRING);
sbLocal.append(junk);
sbLocal.append(ANOTHER_STRING);
sbLocal.append(junk + 1);
if (sbLocal != sb) {
sbLocal.toString();
}
return sbLocal.length() - start;
}
public String conclude() {
if (sb != null) {
return sb.toString();
}
return null;
}
}
private static class TestStringBuilder implements Tester {
protected StringBuilder sb;
public TestStringBuilder() {
}
public void init() {
}
public int test(final long junk) {
final StringBuilder sbLocal = sb == null ? new StringBuilder() : sb;
final int start = sbLocal.length();
sbLocal.append(LONG_STRING);
sbLocal.append(1234);
sbLocal.append(ANOTHER_STRING);
sbLocal.append(junk);
sbLocal.append(ANOTHER_STRING);
sbLocal.append(junk + 1);
if (sbLocal != sb) {
sbLocal.toString();
}
return sbLocal.length() - start;
}
public String conclude() {
if (sb != null) {
return sb.toString();
}
return null;
}
}
public static void main(final String[] args) {
new CatTester().test();
}
private final DateFormat DF = new SimpleDateFormat("ss'.'SSS'ms'");
private long loopTest(final String name, final Tester tester, final int
loops) {
final long start = System.currentTimeMillis();
tester.init();
final long initTime = System.currentTimeMillis();
long junk = 0;
for (int i = 1; i < loops; i++) {
junk += tester.test(junk);
}
final long appendTime = System.currentTimeMillis();
tester.conclude();
if (name != null) {
System.out.println(String.format("%s> Init: %s, Loop: %s,
End: %s, Total: %s.",
name,
timestamp(start, initTime),
timestamp(initTime, appendTime),
timestamp(appendTime),
timestamp(start))
);
}
return junk;
}
private void test() {
final int loops = 100000;
// To warm up the VM, HotSpot etc
loopTest(null, new TestFastCat(), loops);
final long length = loopTest(null, new TestStringBuilder(),
loops) / 10;
loopTest(null, new TestStringBuffer(), loops);
loopTest(null, new TestFastCatReuse(loops), loops);
loopTest(null, new TestStringBufferReuse(length), loops);
loopTest(null, new TestStringBuilderReuse(length), loops);
for (int i = 0; i < 3; ++i) {
System.out.println("Fresh SB/FCs:");
loopTest("Cat", new TestFastCat(), loops);
loopTest("Buf", new TestStringBuffer(), loops);
loopTest("Bui", new TestStringBuilder(), loops);
System.out.println("Reused SB/FCs:");
loopTest("Cat", new TestFastCatReuse(loops), loops);
loopTest("Buf", new TestStringBufferReuse(length), loops);
loopTest("Bui", new TestStringBuilderReuse(length), loops);
}
}
private String timestamp(final long start) {
return timestamp(start, System.currentTimeMillis());
}
private String timestamp(final long start, long endTime) {
return DF.format(new Date(endTime - start));
}
private static class TestFastCatReuse extends TestFastCat {
private final int loops;
public TestFastCatReuse(int loops) {
this.loops = loops;
}
public void init() { sb = new FastCat(loops * 6); }
}
private static class TestStringBufferReuse extends TestStringBuffer {
private final long length;
public TestStringBufferReuse(long length) {
this.length = length;
}
public void init() { sb = new StringBuffer((int) length);}
}
private static class TestStringBuilderReuse extends TestStringBuilder {
private final long length;
public TestStringBuilderReuse(long length) {
this.length = length;
}
public void init() { sb = new StringBuilder((int) length); }
}
}