Во время некоторой разработки я столкнулся с проблемой конкатенации строк, которая кажется медленной, если делать это вручную вместо встроенной функции.
<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 мс. При замене ArrayAppend на cfset цикл становится намного быстрее.
Любая идея о том, что я делаю неправильно?
редактировать: после некоторого дополнительного тестирования мы пришли к следующим результатам:
Используемый скрипт:
<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 final):
Пустой цикл 10 000: 0,001 секунды
Пустой цикл 100 000: 0,013 секунды
Цикл 100 000 cfset: 0,05 секунды
Цикл 10 000 java array set: 8,095 секунды
loop 100 000 arrayAppend: 1,96 секунды
loop 100 000 array set через скобки: 2,103 секунды
Adobe CF 10:
Пустой цикл 10 000: 0,002 секунды
Пустой цикл 100 000: 0,059 секунды
Цикл 100 000 cfset: 0,115 секунды
Цикл 10 000 java array set: 0,014 секунды
loop 100 000 arrayAppend: 0,139 секунды
loop 100 000 array set через скобки: 0,15 секунды
Есть идеи/идеи по этому поводу?
Спасибо.
редактировать2:
моя проблема в реальном мире:
<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>
dummyArray = createObject("java", "java.util.ArrayList"); dummyArray.add("00000")
на Lucee 4.5, и это работает хорошо. - person John Whish   schedule 18.11.2015cfsavecontent
было быстрее, чем использование массивов для построения строк: cfsimplicity.com/101/string-concatenation-in-lucee - person CfSimplicity   schedule 21.11.2015