Frage

Wie kann ich den folgenden Code zu optimieren, die derzeit mehr als 2 Minuten in Anspruch nimmt aus einem Pool von über 100 K Datensätze über 800+ Datensätze abzurufen und Schleife, Rückkehr 6 Felder pro Datensatz (fügt ca. 20 Sekunden pro Zusatzfeld):

<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>
War es hilfreich?

Lösung

Wie groß ist die Liste der Elemente für die innere Schleife?

Der Wechsel zu einem Array Macht schneller, wenn es eine signifikant große Anzahl von Elementen ist.

ich umgesetzt haben, dies neben X0n Vorschläge ...

<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>

Andere Tipps

Es ist schon eine lange Zeit, da ich CF berühren, aber ich kann einige Hinweise in Pseudo-Code geben. Zum einen ist dieser Ausdruck extrem ineffiziente:

# theObject.Get_Item (row) .Get_Properties () Get_Item (col) .Get_Count (.) - 1 #

Nehmen Sie den ersten Teil zum Beispiel Get_Item (row) - Ihr Code verursacht CF, um die Zeile und seine Eigenschaften für jede Iteration der Schleife # column # gehen abzurufen; und zu allem, Sie tun, dass ZWEIMAL pro Iteration von column (einmal für Schleife und wieder für die innere cfset). Wenn man darüber nachdenkt, es braucht nur die Zeile für jede Iteration der äußeren Schleife abgerufen werden (von # sfstart # #cfend). Also, in Pseudo-Code wie folgt vorgehen:

  

für jede Zeile zwischen Anfang und Ende

     
    

cfset Requisiten = # theobject.get_item (row) .get_properties () #

         

für jede Spalte in #columnlist #

         
      

cfset currentcol = # props.getitem (col) #

             

cfset count = # currentcol.getcount () - 1 #

             

foreach Artikel von 0 bis #count #

             
        

cfset # currentcol.getItem (Artikel) # etc ...

      
    
  

Sinn? Jedes Mal, wenn Sie ein Schleife, Cache-Objekte ein, die in einer Variablen in diesem Bereich (oder untergeordneten Bereichen) wiederverwendet werden. Das heißt, Sie sind nur die Spalte Objekt einmal pro Iteration der Spalte Schleife greifen. Alle Variablen in den äußeren Bereichen definiert sind in den inneren Bereichen zur Verfügung, wie man in sehen kann, was ich oben getan haben. Ich weiß, seine verlockend zu schneiden und aus vorherigen Zeilen einfügen, aber nicht. Es ist nur weh tut man am Ende.

hoffe, das hilft,

Oisin

Darüber hinaus wird dies wahrscheinlich eine Verlangsamung eines cftry Block in jeder Schleife mit nach unten ziemlich viel. Sofern Sie einzelne Zeilen erwarten zu scheitern (und Sie müssen von diesem Punkt fortsetzen), würde ich einen einzigen try / catch-Block für den gesamten Prozess vor. Try / catch ist eine teuere Operation.

Ich würde denken, dass Sie würde tun so viele Bewertungen innerhalb von Loops zu stoppen und stattdessen Variablen zählt, Zeiger auf die Spalte Objekt zu halten und Ihre Rohr delim Zeichenfolge zu halten, bis Sie bereit sind, zu verpflichten das Abfrageobjekt. Wenn ich das Refactoring richtig gemacht haben, sollten Sie eine Verbesserung feststellen, wenn Sie den Code verwenden unter:

<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>

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top