填充数组时的显着时间差异(Coldfusion vs Railo)

时间:2015-11-18 10:55:47

标签: arrays performance coldfusion cfml railo

在一些开发过程中,我遇到了串联字符串的问题,当手动执行而不是本机函数时这似乎很慢

<cfset start = gettickcount()>
<cfset dummyArray = ArrayNew(1) />
<cfset concatedString = "" />
<cfset concatenatedByFunctionString = "" />


<cfloop from="1" to="100000" index="i">
       <cfset arrayAppend(dummyArray, RandRange(1000000, 9999999)) />
</cfloop>


<cfoutput>Prepping data: #(gettickcount() - start)/1000# seconds<br/></cfoutput>


<cfset start = gettickcount()>
<cfloop from="1" to="100000" index="j">
       <cfset concatedString = concatedString & dummyArray[j] />
</cfloop>

<cfoutput>concatenating data in loop: #(gettickcount() - start)/1000# seconds<br/></cfoutput>

<cfset start = gettickcount()>
<cfset concatenatedByFunctionString = arraytoList(dummyArray,'')/>
<cfoutput>concatenating data in arraytoList function: #(gettickcount() - start)/1000# seconds<br/></cfoutput>


<cfif structKeyExists(url,'debug')>
       in loop:<br/>
       <cfdump var="#concatedString#"/>
       in function:<br/>
       <cfdump var="#concatenatedByFunctionString#"/>
</cfif>

然而,这不是问题。当您在Coldfusion中运行此脚本时,准备数据所需的时间大约为150毫秒,而在Railo中则超过3000毫秒。使用cfset替换ArrayAppend时,循环变得更快。

对我做错了什么想法?

编辑:经过一些额外的测试后,我们得到了以下结果:

使用的脚本:

<cfset start = gettickcount()>
<cfloop from="1" to="10000" index="i">
</cfloop>
<cfoutput>Empty loop 10 000: #(gettickcount() - start)/1000# seconds<br/></cfoutput>


<cfset start = gettickcount()>
<cfloop from="1" to="100000" index="i">
</cfloop>
<cfoutput>Empty loop 100 000: #(gettickcount() - start)/1000# seconds<br/></cfoutput>


<cfset start = gettickcount()>
<cfloop from="1" to="100000" index="i">
       <cfset local.tmp = 1/>
</cfloop>
<cfoutput>loop 100 000 cfset: #(gettickcount() - start)/1000# seconds<br/></cfoutput>


<cfset start = gettickcount()>
<cfscript>
       string = CreateObject("java", "java.lang.String");
       array = CreateObject("java", "java.lang.reflect.Array");
       dummyArray = array.newInstance(string.getClass(), 10000);
</cfscript>
<cfloop from="0" to="9999" index="i">
       <cfset array.set(dummyArray, i, "00000") />
</cfloop>
<cfoutput>loop 10 000 java array set: #(gettickcount() - start)/1000# seconds<br/></cfoutput>


<cfset start = gettickcount()>
<cfset dummyArray = ArrayNew(1) />
<cfloop from="1" to="100000" index="i">
       <cfset arrayAppend(dummyArray, '00000') />
</cfloop>
<cfoutput>loop 100 000 arrayAppend: #(gettickcount() - start)/1000# seconds<br/></cfoutput>


<cfset start = gettickcount()>
<cfset dummyArray = ArrayNew(1) />
<cfloop from="1" to="100000" index="i">
       <cfset dummyArray[i] = '00000' />
</cfloop>
<cfoutput>loop 100 000 array set via brackets: #(gettickcount() - start)/1000# seconds<br/></cfoutput>

输出:

Railo(4.2.1.008决赛):
空循环10 000:0.001秒
空循环100 000:0.013秒
循环100 000 cfset:0.05秒
循环10 000 java数组:8.095秒
循环100 000 arrayAppend:1.96秒
循环100 000阵列通过括号设置:2.103秒


Adob​​e CF 10:
空循环10 000:0.002秒
空循环100 000:0.059秒
循环100 000 cfset:0.115秒
循环10 000 java数组:0.014秒
循环100 000 arrayAppend:0.139秒
循环100 000阵列通过括号设置:0.15秒


对此有什么见解/想法?

感谢。

EDIT2:

我的现实世界问题:

<cfinclude template="/queries/pr_web_shop_country_seo.cfm" >
<cfloop query="qry_web_shop_country_seo">
    <cfif qry_web_shop_country_seo.generate_sitemap eq 1>

        <cfset types_to_generate = ArrayNew(1) />
        <cfset types_to_generate[1] = "PRODUCTS" />

        <cfset indexList = ArrayNew(1) />

        <cfset locale = qry_web_shop_country_seo.country_code />
        <cfset id_language = qry_web_shop_country_seo.id_language_default />
        <cfset file_suffix = "-" & replace(qry_web_shop_country_seo.url_domain,'.','-','ALL') & ((qry_web_shop_country_seo.url_suffix eq "")? "" : "-" & qry_web_shop_country_seo.url_suffix) />
        <cfinclude template="/queries/pr_seo_urls.cfm">

        <cfloop array="#types_to_generate#" index="type">

            <cfswitch expression="#type#">

                <cfcase value="PRODUCTS">

                    <cfset productData = ArrayNew(2)>
                    <cfset counter = 1>

                    <cfloop query="qry_seo_urls">
                        <cfif qry_seo_urls.source eq 'PRODUCT'>
                            <cfset arrayAppend(
                                    productData[Ceiling(counter/max_link_list)]
                                    ,url_prefix & qry_web_shop_country_seo.url_domain & qry_web_shop_country_seo.root & qry_seo_urls.seo_url)
                            />
                            <cfset counter = counter + 1 />
                        </cfif>
                    </cfloop>
                </cfcase>
            </cfswitch>
        </cfloop>
    </cfif>
</cfloop>

1 个答案:

答案 0 :(得分:2)

如果您正在寻找最快的解决方案,请尝试使用java.util.ArrayList。我在Lucee 4.5上试过它并且表现很好,所以可能适合你的需要。

<cfset start = gettickcount()>
<cfset dummyArray = createObject("java", "java.util.ArrayList")>

<cfloop from="0" to="9999" index="i">
    <cfset dummyArray.add("00000")>
</cfloop>

<cfoutput>
loop 10,000 java.util.ArrayList add: #(gettickcount() - start)/1000# seconds
</cfoutput>