import java.util.Calendar;
public class MainClass
{
public static void main(String args[])
{
String s = new String("ABCD");
long swapStart = Calendar.getInstance().getTimeInMillis();
for(int i=0; i<s.length()/2;i++)
{
char left = s.charAt(i);
char right = s.charAt(s.length()-(i+1));
s=s.substring(0, i)+right+s.substring(i+1, s.length()-(i+1))+left+s.substring(s.length()-i, s.length());
}
long swapStop = Calendar.getInstance().getTimeInMillis();
long bufStart = Calendar.getInstance().getTimeInMillis();
String str = new String("ABCD");
StringBuffer strBuf = new StringBuffer(str);
str = strBuf.reverse().toString();
long bufStop = Calendar.getInstance().getTimeInMillis();
System.out.println(swapStop-swapStart);
System.out.println(bufStop-bufStart);
}
}
***** in the new String("ABCD") of the string if i provide a really big string say couple of hundreds of alpha numerics
*****in the console output is :
61
0
*****the stringbuffer always calculated in 0 milli seconds and my char swapping algo takes as per the string size
Q. how come my swap algo can't do it in 0 milli seconds and why stringbuffer always does it in 0 milli seconds ?
I checked the Java Source Code and StringBuffer.reverse() is implemented as follows :
public AbstractStringBuilder reverse() {
boolean hasSurrogate = false;
int n = count - 1;
for (int j = (n-1) >> 1; j >= 0; --j) {
char temp = value[j];
char temp2 = value[n - j];
if (!hasSurrogate) {
hasSurrogate = (temp >= Character.MIN_SURROGATE && temp <= Character.MAX_SURROGATE)
|| (temp2 >= Character.MIN_SURROGATE && temp2 <= Character.MAX_SURROGATE);
}
value[j] = temp2;
value[n - j] = temp;
}
if (hasSurrogate) {
// Reverse back all valid surrogate pairs
for (int i = 0; i < count - 1; i++) {
char c2 = value[i];
if (Character.isLowSurrogate(c2)) {
char c1 = value[i + 1];
if (Character.isHighSurrogate(c1)) {
value[i++] = c1;
value[i] = c2;
}
}
}
}
return this;
}
Q. Please explain the surrogate thing.
Q1: There is a performance difference because your swapping code creates a lot of String
objects that get operated on, while the other routine works directly with a char array and requires no additional object creation. Let's examine your line of code:
s=s.substring(0, i)+right+s.substring(i+1, s.length()-(i+1))+left+s.substring(s.length()-i, s.length());
It does this kind of work:
s = [new String 1] + char + [new String 2] + char + [new String 3]
That's 4 new String
objects (the three shown, plus the one resulting from the addition of String
objects. Also, each of the 3 new strings shown has a call to substring which takes time to process. In addition you do all of this work in a for-loop so it gets repeated for each character!
String manipulation is convenient but expensive. Array manipulation is direct, requires no additional object or blocks of memory, so is much faster.
Q2: Surrogates are a special case of unicode character created to handle longer unicode characters. See this article for more details. The order of the hi/low parts of the surrogate are important so it would be wrong for the swap code to reverse those two characters, so if they are found, their order is put back the way it should be.