3

I am not an expert in Java; I am hoping that someone on this list who are more proficient in Java can help me out.

I have the following codes on my current server.

<cfset var buffer = CreateObject("java", "java.lang.StringBuffer").init("") />
<cfset buffer.append(variables.myVar) />

I am trying to move these codes to another server. The problem is that this new server (shared hosting) does not allow invoking of a Java Object. So, I changed them to the followings.

<cfset var buffer = "" />
<cfset var buffer = buffer & variables.myVar />

My question is, are the new codes equivalent to the old ones? What are the advantages of using java.lang.StringBuffer?

Thanks in advance, Monte

Monte Chan
  • 1,193
  • 4
  • 20
  • 42

3 Answers3

6

No, the "new" code is less efficient when used in a heavy loop.

You can emulate StringBuffer with an array.

<cfset var buffer = ArrayNew(1)>
<cfset ArrayAppend(buffer, variables.myVar1)>
<cfset ArrayAppend(buffer, variables.myVar2)>
<!--- more of these --->
<cfset result = ArrayToList(buffer, "")>

However: If you are not concatenating hundreds or thousands of strings in a row, there is little benefit in using StringBuffer. You can go with & in most cases.


I have done some testing (on a ColdFusion 7 server w/ Java 1.4, more recent editions might score differently).

All times are milli-seconds The results are averaged over 10 repeats (except the one in square brackets as this took virtually forever).

The following is the measurement of iteratively concatenating a single letter N times.

iterations   concat   array   cfsave   string
                             content   buffer
       100        0       0        0        2
      1000        4       4        2       22
     10000      168      29       33      219
    100000   30,781     168      293    1,575

The following is the result of iteratively concatenating a string of length 10 N times:

iterations   concat   array   cfsave   string
                             content   buffer
       100        0       0        0        4
      1000       25       0        2       24
     10000    1,242      33       31      232
    100000 [410,979]    180      373    2,082

Note how basic string concatenation gets rapidly more inefficient the more iterations you do and the longer the string gets. The other methods show more linar behavior.

Further notice that the StringBuffer's performance is also tied to its initial size. If you dimension it too small (i.e. by calling init("") instead of .init(10000), for example) then it is forced to re-allocate more space when it runs out, which also takes time. For the sake of test, I initialized it with exactly the amount of space it would need.

Tomalak
  • 332,285
  • 67
  • 532
  • 628
2

Technically, no. But practically, I think it is fine.

StringBuffer is a mutable object, hence the reason you are able to append(). ColdFusion strings, like Java Strings) are immutable, so you need to create a new string and overwrite the old (which is what you are doing in the above example).

I am not sure, but you might see a minor (milliseconds) performance different, and you are, technically, creating more objects with the ColdFusion method, but since you are using shared hosting you probably don't really care about that kind of performance difference anyway.

Unless you are doing hundreds or more of these, I doubt you will notice a difference.

Jason Dean
  • 9,585
  • 27
  • 36
  • JIT compiler would be smart enough to optimize the basic string append "+=" into using StringBuffer if and when it sees fit, but not sure about CF's "&=". See: http://stackoverflow.com/questions/599161/best-way-to-convert-an-arraylist-to-a-string – Henry Jun 06 '11 at 16:48
1

Use <cfloop> inside <cfsavecontent>. If what you're constructing is space-sensitive, please double the output for extra space/newline, and code your <cfloop> and <cfsavecontent> accordingly (i.e. in one line).

I've come cross tests that have shown that it is even faster then Java's StringBuilder.

Update: http://www.cfinsider.com/index.cfm/2009/10/23/High-Performance-String-Concatenation-in-ColdFusion

from fastest to slowest:

  1. ArrayAppend() and then ArrayToList()
  2. <cfsavecontent>
  3. StringBuilder's append()
  4. basic string concat using &
Henry
  • 32,689
  • 19
  • 120
  • 221