It is said that char[] performs better that StringBuilder and StringBuilder performs better than string in terms of concatenation.
In my test there is no significant difference between using StringBuilder and string inside the loop. In fact the char[] is the slowest.
I am testing against the same table with 44 columns and 130,000 rows the query is select * from test
Can someone help me see if I did something wrong?
The following is the code
//fetchByString(rd, fldCnt, delimiter, sw); // duration: 3 seconds
//fetchByBuilder(rd, fldCnt, delimiter, sw, rsize); // duration: 3 seconds
//fetchByCharArray(rd, fldCnt, delimiter, sw, rsize); // duration: 7 seconds
private void fetchByString(OracleDataReader pReader, int pFldCnt, string pDelimiter, StreamWriter pWriter)
{
while (pReader.Read())
{
string[] s = new string[pFldCnt];
for (Int32 j = 0; j < pFldCnt; j++)
{
if (pReader.IsDBNull(j))
{
s[j] = "";
}
else
{
s[j] = pReader.GetValue(j).ToString(); // correct value
}
}
pWriter.WriteLine(string.Join(pDelimiter, s));
}
}
private void fetchByBuilder(OracleDataReader pReader, int pFldCnt, string pDelimiter, StreamWriter pWriter, int pRowSzie)
{
StringBuilder sb = new StringBuilder(pRowSzie);
while (pReader.Read())
{
for (Int32 j = 0; j < pFldCnt; j++)
{
if (pReader.IsDBNull(j))
{
//sb.Append("");
sb.Append(pDelimiter);
}
else
{
sb.Append(pReader.GetValue(j).ToString()); // correct value
sb.Append(pDelimiter);
}
}
pWriter.WriteLine(sb.ToString());
sb.Clear();
}
}
private void fetchByCharArray(OracleDataReader pReader, int pFldCnt, string pDelimiter, StreamWriter pWriter, int pRowSzie)
{
char[] rowArray;
int sofar;
while (pReader.Read())
{
rowArray = new char[pRowSzie];
sofar = 0;
for (Int32 j = 0; j < pFldCnt; j++)
{
if (pReader.IsDBNull(j))
{
pDelimiter.CopyTo(0, rowArray, sofar, pDelimiter.Length);
sofar += pDelimiter.Length;
}
else
{
pReader.GetValue(j).ToString().CopyTo(0, rowArray, sofar, pReader.GetValue(j).ToString().Length);
sofar += pReader.GetValue(j).ToString().Length;
pDelimiter.CopyTo(0, rowArray, sofar, pDelimiter.Length);
sofar += pDelimiter.Length;
}
}
string a = new string(rowArray).TrimEnd('\0');
pWriter.WriteLine(a);
}
}
StringBuilder is preferred over string concat because string concat frequently has to allocate temporary intermediate copies of the data with each + operator, which chews up a lot of memory fast and requires copying data multiple times. StringBuilder.Append() is internally optimized to avoid copying or allocating the subsegments multiple times. All the work happens at StringBuilder.ToString, when the final size of the output string is known and it can be allocated in one call.
Your test cases aren't using string concat. You allocate a bunch of string fragments into an array of string, and then you call String.Join. That's essentially what StringBuilder does internally. Even after you remove the overhead of data I/O that may be dominating the benchmark times, I would expect String.Join() and StringBuilder.ToString() to produce similar performance.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With