14. juli 2005 - 17:36Der er
27 kommentarer og 1 løsning
afviklingstid stiger voldsomt
Hey...
Jeg har følgende ASP kode, hvor afviklingstiden stiger voldsomt. Koden er et jubel script JA, men den skal åbne alle de .xls filer som findes i en mappe, og løbe alle igennem, hvor den tager bestemte kolonner, og tilføjer hver enkel række i en access db, hvis de ikke er tilføjet i forvejen fra denne fil (tjekker på indhold fra en bestemt kolonne).
scriptet virker somså fint nok, men selvom den kun kører gennem 2 ens filer (forskellig navn), tager nummer 2 over dobbelt så lang tid som den første - er de rnogle som kan forklare hvorfor, og evt. komme med forbedringer?
-Det skal lige siges, at det SKAL være excel filer den henter fra, da jeg ikke er herre over dem.
-----------Kode start------------------------------------------- <!-- #include File="func.asp" !--> <% set objFS=Server.CreateObject("Scripting.FileSystemObject") 'Overwriting old indexDB with an empty indexDB objFS.CopyFile strDBPath & ".bak", strDBPath, true
'Connect to indexDB.mdb connectDB()
Dim arrControl() ReDim arrControl(1)
intCountAll = 0 intCountValid = 0 intFiles = 0 Set objFolder=objFS.GetFolder(Server.MapPath(strXlsFolder)) Set objRS = Server.CreateObject("ADODB.Recordset")
'Loop through all excel files for each objFile in objFolder.files strFileName = objFile.Name If Right(strFileName,3) = "xls" Then 'Connect to selected Excel file connectXls(Server.MapPath(strXlsFolder & strFileName))
' Select and open Sheet objRS.Open "select [KANAL],[PLAC/POS],[BETEGNELSE] from [" & strSheetName & "$];", objXlsConn
'Loop through the whole excel file do while not objRS.EOF blnWrite = True intCountAll = intCountAll + 1 strPos = objRS.fields.item("PLAC/POS").value
'Testing for empty field If (strPos & "x") = "x" then blnWrite = false End If
'Testing for dublet i = UBound(arrControl) Do while ((i >= LBound(arrControl)) and (blnWrite = true)) If (arrControl(i)) = (strPos) then blnWrite = false End if i = i - 1 Loop
if blnWrite = true then 'Save record in array ReDim Preserve arrControl(intCountAll) arrControl(intCountAll) = strPos
'If intCount is multiple of 50 -> update status if (intCountAll mod 50) = 0 then writeStatus intcountAll, "<br>" & intcountValid & " records added in DB<br>" & intFiles & " files completed" end if
'Move to next row in excel-sheet objRS.movenext loop
forklaringen er måske logisk nok Du fylder jo et array op (arrControl) efterhånden som du løber igennem Jo større array des længere tid tager det at løbe det igennem Ved den første fil starter det som et tomt array Ved den anden fil starter det som et fuldt array Og hvis der er vildt mange poster i arrayet ja så kan det mærkes
og så ved jeg ikke hvor effektiv en redim preserve er i asp Altså en array udvidelse For jo flere elementer der er i arrayet kunne man måske forestille sig at sådan en operation også tager længere og længere tid
hmmm... så er det måske bare den langsomme inet forb. jeg sidder på, som spiller mig et pus... har du et eks. ved hånden til brug af scripting.dictionary?
så jeg forkert eller hvad.. orker ikke lige to minutter mere ;o) Men når den udskriver din slut størrelse på dit array Så skriver den at det er større anden gang end første fil gør den ikke?
ikke noget rigtig godt til det her men du kan læse kort om det her http://msdn.microsoft.com/library/default.asp?url=/library/en-us/script56/html/jsobjDictionary.asp Ideen er at hver indgang har en "key" og en "value" Du opretter blot en ny indgang ved at angive en unik ny nøgle samt værdien denne nøgle skal have I dit tilfælde kunne du lave nøgler som indeholder tomme værdier Så kan du blot spørge til om nøglen eksisterer eller ej Når du er færdig sættes dit dictionary til Nothing og er så "helt dødt"
nå ja og det skulle så være halvdelen! for 2216 er jo ikke det halve af 8190 ;o) Den anden halvdel kan være fordi du tæller intCountAll op uanset hvad og bruger netop den til at resize med -- Dvs første fil fylder dit array op Næste fil går igang Den finder en dublet og tæller intCountAll op Lad os sige den looper 1000 igennem som alle eksisterer så er intCountAll 1000 større Hvad nu hvis den så finder en som ikke har en dublet? Jo så laver den arrayet 1000 pladser større for kun at putte een værdi ind :o/ -- Jeg vil foreslå dig at lave en arrayCount eller lignende som holder øje med arrayts størrelse seperat :o)
ough - yeps, det er i hvert fald en fejlkilde ;) men selvom det bliver rettet virker det ikke specielt meget hurtigere, så kigger lige på Scripting.Dictionary - tingen
oki, med begge rettelser for mener også det med intCountAll har kunne give problemer? Men ja ellers tag et kig på den Jeg ved ikke hvordan den er implementeret men jeg forestiller mig at den appender et element frem for at kopiere det hele, og det må være hurtigere :o)
oki - takker - din kommentar kl 18:12:26 var ikke lige kommet, så da variablen til at tælle rækker med kun bliver incrementeret når det er nødvendig ;) er den nede på 7 sek for første fil, og 14 sek for anden fil :D DET kan jeg bruge til noget :D -men vil stadig lige prøve at kigge på den anden metode
argh.. mig som ser forkert, begge tager 7 sek, så hvis du smider et svar, får du nogle velfortjente point - du har i hvert fald sparet mig for en masse hovedpine ;)
hehe engang imellem stirrer man sig jo blind på tingene :o) Glad jeg kunne hjælpe og godt det virker
Hvis du nu finder på at benytte dictionary i stedet og kan se en tidsforskel så må du da meget gerne lige skrive det, for jeg er lidt nysgerrig om det er hurtigere, jeg har bare ikke så meget test materiale at det rigtig kan måles
så fik jeg list aftensmad, og kigget på noget dictionary. konklusion: Det er lidt hurtigere, du kan se tider herunder, med 6 sek pr fil, hvor den med alm. array var på 7 sek
Time for file: 1 :: 6seconds Time for file: 2 :: 6seconds 11948 records processed 414 records added in DB Update Complete in 12 seconds
okay... men jeg holder mig til dictionary, da den både er hurtigere (sådan som jeg har det strikket sammen) og gør koden meget mere enkel, fx for at tjekke for dubletter, er det bare dictionary.exists("")
Synes godt om
Ny brugerNybegynder
Din løsning...
Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.