文字列連結を計測

Coldfusionの文字列連結は私が知る限り2通りありまして、どちらが効率的なのか疑問を持ったのでちょいと試してみました。

<!---// そのいち //--->
<cfset Variables.s1=Variables.s2 & Variables.s3/>
<!---// そのに //--->
<cfset Variables.s4="#Variables.s5##Variables.s6#"/>

調査はこの2通りに対してで、以下のようなCFMファイルを作ってみました。

<html>
  <body>
    <cfoutput>
      <cfset Variables.loopCount=20000/>
      <!---// >まとめて文字列化 //--->
      <cfset Variables.d1=Now()>
      開始:#getOutputDate(Variables.d1)#<br/>
      <cfset Variables.s=""/>
      <cfloop index="Variables.idx" from="1" to="#Variables.loopCount#">
        <cfset Variables.s="#Variables.s##Variables.idx#" & "#Chr(10)#"/>
      </cfloop>
      <cfset Variables.d2=Now()/>
      終了:#getOutputDate(Variables.d2)#<br/>
      <cfset Variables.d3=DateDiff("s", Variables.d1, Variables.d2)/>
      <strong>処理時間=#Variables.d3#</strong>
      <hr/>
      <!---// あんぱさんどをつかう //--->
      <cfset Variables.d1=Now()>
      開始:#getOutputDate(Variables.d1)#<br/>
      <cfset Variables.s=""/>
      <cfloop index="Variables.idx" from="1" to="#Variables.loopCount#">
        <cfset Variables.s=Variables.s & "#Variables.idx##Chr(10)#"/>
      </cfloop>
      <cfset Variables.d2=Now()/>
      終了:#getOutputDate(Variables.d2)#<br/>
      <cfset Variables.d3=DateDiff("s", Variables.d1, Variables.d2)/>
      <strong>処理時間=#Variables.d3#</strong>
      <hr/>
    </cfoutput>
  </body>
</html>
<cffunction name="getOutputDate">
  <cfargument name="date" type="date" required="true"/>
  <cfset var ret="#DateFormat(Arguments.date, 'yyyy-mm-dd')##TimeFormat(Arguments.date, 'hh:mm:ss:lllll')#"/>
  <cfreturn ret/>
</cffunction>

無駄に文字列連結をするだけなんですが、上はアンパサンド、下はまとめて文字列化しています。また、最後に書いてあるFunctionは、Now()で得た日時に書式を与えています。で、変に最適化されてるとか嫌なので、上と下を入れ替えてそれぞれ実施してみました。
ミリ秒以下切捨てで、

◆上:まとめて文字列化/下:アンパサンド=上5秒/下2秒
◆上:アンパサンド/下:まとめて文字列化=上5秒/下4秒

だそうです。


個人的には、まとめて文字列化の方がスッキリ見えて好きだったのですが、どうもあまり効率の良い処理ではないようです。ただし、まとめて文字列化した方が2回目で若干早くなっているのは、これはコンパイルのコストが関係しているのでしょう。(Coldfusionは、CFMLで記述したコードを一度JSPにしているらしい。妙なコードを書いてBugを出すと、たまにJSPの親玉がjavaなんちゃら.なんとかExceptionを吐きます)

で、ちょっと悔しいので前述の2つのパターンで追加している文字列を、Function(引数で追加したい文字列を受け取り、何も加工せずにreturn)経由で取得するようにした結果、

◆上:関数をかましてあんぱさんどをつかう/下:関数をかましてまとめて文字列化=上5秒/下5秒

と出ました。


まとめて文字列化を使うって事は、何も行わない関数をフィルタっぽく使うのと同義みたいです。


もう少し深く掘り下げるには、恥ずかしながら私にまだまだ知識が足りないので、とりあえずここまでとします。
※)エントリを書いてから30分くらいで、コードと結果を書き直したました。