2011-06-06 44 views
2

我不是Java的專家;我希望這個名單上的更精通Java的人能幫助我。ColdFusion中的「regular」字符串操作邏輯能替換java.lang.StringBuffer嗎?

我在我的當前服務器上有以下代碼。

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

我試圖將這些代碼移動到另一臺服務器。問題是這個新服務器(共享主機)不允許調用Java對象。所以,我將它們改爲以下。

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

我的問題是,是新的代碼相當於舊的?使用java.lang.StringBuffer有什麼好處?

由於提前, 蒙

+1

是否有任何理由使用StringBuffer而不是StringBuilder? – 2011-06-06 17:14:44

+0

如果同步是一個問題,你可能需要StringBuffer。雖然它可能只是舊代碼。 IIRC,StringBuilder直到jvm 1.5才被添加。 – Leigh 2011-06-06 18:26:13

+0

彼得,使用StringBuffer的代碼是由其他人完成的。 – 2011-06-06 20:12:13

回答

5

沒有,在沉重的循環使用時,「新」的代碼效率不高。

您可以使用數組模擬StringBuffer。

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

但是:如果您沒有連接成百上千個字符串,使用StringBuffer幾乎沒有什麼好處。在大多數情況下,您可以使用&


我已經做了一些測試(在帶有Java 1.4的ColdFusion 7服務器上,更新的版本可能得分不同)。

所有時間都是毫秒結果平均10次重複(除了方括號內的數字,因爲這幾乎是永久性的)。

以下是迭代連接單個字母 N次的度量。

 
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 

以下是反覆串聯長度的字符串10 N次結果:

 
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 

注基本字符串連接如何得到迅速更低效的重複你做得越多越長,字符串獲取。其他方法顯示更多的linar行爲。

請注意,StringBuffer的性能也與其初始大小有關。如果尺寸太小(例如,通過調用init("")而不是.init(10000)),那麼它在耗盡時會被迫重新分配更多空間,這也需要時間。爲了測試,我用它所需要的空間量來初始化它。

+0

感謝您的快速響應。 – 2011-06-06 15:48:33

+0

假設Adobe的ArrayToList()的實現是有效的? – Henry 2011-06-06 16:51:25

+0

@Henry:它會在底層數組上調用join()。 – Tomalak 2011-06-06 16:53:38

2

從技術上講,沒有。但實際上,我認爲這很好。

StringBuffer是一個可變對象,因此您可以追加()的原因。像Java字符串一樣的ColdFusion字符串)是不可變的,所以你需要創建一個新的字符串並覆蓋舊的(這就是你在上面的例子中所做的)。在技​​術上,您可以使用ColdFusion方法創建更多對象,但由於您使用的是共享主機,因此您可能並不關心無論如何,這種性能差異。

除非你正在做數百個或更多的這些,否則我懷疑你會注意到一個區別。

+0

非常感謝您的回覆。 – 2011-06-06 15:54:33

+0

JIT編譯器足夠聰明,可以優化基本字符串,當它看起來合適時,使用StringBuffer追加「+ =」,但不確定CF的「&=」。見:http://stackoverflow.com/questions/599161/best-way-to-convert-an-arraylist-to-a-string – Henry 2011-06-06 16:48:03

1

使用<cfloop>裏面<cfsavecontent>。如果您構建的是空間敏感的,請將輸出結果加倍以獲取額外的空間/換行符,並相應地編碼您的<cfloop><cfsavecontent>(即在一行中)。

我來過交叉測試,表明它甚至比Java的StringBuilder更快。

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

從最快到最慢:

  1. ArrayAppend(),然後ArrayToList()
  2. <cfsavecontent>
  3. 的StringBuilder的append()
  4. 基本字符串連接使用&
+1

這很棒,+1 – Tomalak 2011-06-06 17:15:06