2008-09-17 75 views
2

如何優化以下代碼,該代碼目前需要2分鐘以上才能檢索並通過超過100K記錄的池中的800多條記錄進行循環,每個記錄返回6個字段(每個附加字段添加大約20秒):如何加快ColdFusion中.NET AD的數據檢索速度?

<cfset dllPath="C:\WINDOWS\Microsoft.NET\Framework\v1.1.4322\System.DirectoryServices.dll" /> 
<cfset LDAPPath="LDAP://" & arguments.searchPath /> 
<cfset theLookUp=CreateObject(".NET","System.DirectoryServices.DirectoryEntry", dllPath).init(LDAPPath) /> 
<cfset theSearch=CreateObject(".NET","System.DirectoryServices.DirectorySearcher", dllPath).init(theLookUp) /> 
<cfset theSearch.Set_Filter(arguments.theFilter) /> 
<cfset theObject = theSearch.FindAll() /> 

<cfloop index="row" from="#startRow#" to="#endRow#"> 
    <cfset QueryAddRow(theQuery) /> 
    <cfloop list="#columnList#" index="col"> 
    <cfloop from="0" to="#theObject.Get_Item(row).Get_Properties().Get_Item(col).Get_Count()-1#" index="item"> 
     <cftry> 
     <cfset theQuery[col][theQuery.recordCount]=ListAppend(theQuery[col][theQuery.recordCount],theObject.Get_Item(row).Get_Properties().Get_Item(col).Get_Item(item),"|") /> 
     <cfcatch type="any"> 
     </cfcatch> 
     </cftry> 
     </cfloop> 
    </cfloop> 
    </cfloop> 

回答

2

內部循環的項目列表有多大?

切換到數組可能如果有大量的項目會更快。

我已經與x0n的建議一起實施了...

<cfset dllPath="C:\WINDOWS\Microsoft.NET\Framework\v1.1.4322\System.DirectoryServices.dll" /> 
<cfset LDAPPath="LDAP://" & arguments.searchPath /> 
<cfset theLookUp=CreateObject(".NET","System.DirectoryServices.DirectoryEntry", dllPath).init(LDAPPath) /> 
<cfset theSearch=CreateObject(".NET","System.DirectoryServices.DirectorySearcher", dllPath).init(theLookUp) /> 
<cfset theSearch.Set_Filter(arguments.theFilter) /> 
<cfset theObject = theSearch.FindAll() /> 

<cfloop index="row" from="#startRow#" to="#endRow#"> 

    <cfset Props = theObject.get_item(row).get_properties() /> 

    <cfset QueryAddRow(theQuery) /> 

    <cfloop list="#columnList#" index="col"> 

     <cfset CurrentCol = Props.getItem(col) /> 

     <cfset ItemArray = ArrayNew(1)/> 
     <cfloop from="0" to="#CurrentCol.getcount() - 1#" index="item"> 
      <cftry> 
       <cfset ArrayAppend(ItemArray , CurrentCol.Get_Item(item))/> 
       <cfcatch type="any"> 
       </cfcatch> 
      </cftry> 
     </cfloop> 
     <cfset theQuery[col][theQuery.recordCount] = ArrayToList(ItemArray , '|')/> 

    </cfloop> 

</cfloop> 
2

自從我接觸CF以來已經很長時間了,但我可以在僞代碼中給出一些提示。一方面,這種表達是極其inefficent:

#theObject.Get_Item(行).Get_Properties()Get_Item(COL).Get_Count() - 1#

在第一個部分,例如,Get_Item(。行) - 您的代碼會導致CF在#columnList#loop的每次迭代中檢索行及其屬性;並且最重要的是,你每次迭代列表都要做TWICE(一次循環,另一次循環內部cfset)。如果你仔細想一想,它只需要檢索外循環的每個迭代的行(從#sfstart#到#cfend)。所以,在僞代碼做到這一點:

的開始和結束

CFSET道具=#theobject.get_item(行).get_properties()#

之間每行每一個山坳在#columnlist#

CFSET currentcol =#props.getitem(COL)#

CFSET計數= #current col.getcount() - 1#0

的foreach項#計數#

CFSET#currentcol.getItem(項目)#等等

有意義嗎?每次進入一個循環時,緩存將在該範圍(或子範圍)中重用的變量中的對象。這意味着您只需在列循環的每次迭代中抓取一次列對象。在外部作用域中定義的所有變量都可以在內部作用域中使用,正如您在上面所做的一樣。我知道它很容易從以前的線中剪切和粘貼,但是不要。它最終只會傷害你。

希望這有助於

[287]莪

+0

計數變量/緩存是沒有必要的 - CF將緩存從/爲CFLOOP值。 (儘管不是在cfscript中的循環語句) – 2008-09-17 18:01:55

+0

我會這麼想,但我試圖證明一個觀點。 – x0n 2008-09-17 19:17:04

1

另外,使用在每個循環中cftry塊很可能放緩下來不少。除非您希望單個行失敗(並且您需要從這一點繼續),否則我會建議爲整個過程設置一個try/catch塊。 Try/catch是一項昂貴的操作。

+0

是的,但在這種情況下,我期望數據不好或丟失......所以我必須忍受。問題:考慮到其他建議,我假設我可以通過再次檢查最低範圍 – Brian 2008-09-17 18:24:42

+0

處的itemCount來繞過這個問題,我不能說CF,但是在任何其他帶有try/catch和異常的語言中,它不是try/catch這是昂貴的,這是例外的創建。這是因爲一個異常包含一個堆棧跟蹤 - 也就是說,直到這一點之前調用的所有方法的列表。 – x0n 2008-09-17 19:15:00

0

我會認爲你要停止做你的循環裏面這麼多的評價,而使用變量來保存計數,指針山坳對象,直到你握住你管DELIM串準備提交給查詢對象。如果我做了正確的重構,你應該,如果你使用下面的代碼注意到一個改進:

<cfloop index="row" from="#startRow#" to="#endRow#"> 
<cfset QueryAddRow(theQuery) /> 
<cfloop list="#columnList#" index="col"> 
    <cfset PipedVals = ""> 
    <cfset theItem = theObject.Get_Item(row).Get_Properties().Get_Item(col)> 
    <cfset ColCount = theItem.Get_Count()-1> 
    <cfloop from="0" to="#ColCount#" index="item"> 
     <cftry> 
     <cfset PipedVals = ListAppend(PipedVals,theItem.Get_Item(item),"|")> 
     <cfcatch type="any"></cfcatch> 
     </cftry> 
    </cfloop> 
    <cfset QuerySetCell(theQuery,col) = PipedVals> 
</cfloop>