Avatar billede hadaps Nybegynder
14. juli 2005 - 17:36 Der 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
       
        'Insert in DB
      strSQL = "insert into Tabel ("
        strSQL = strSQL & "fil,"
        strSQL = strSQL & "pos)"
        strSQL = strSQL & " values( "
        strSQL = strSQL & "'" & Left(strFileName,3) & "',"
        strSQL = strSQL & "'" & strPos & "')"
        objDBConn.execute(strSQL)
        intCountValid = intCountValid + 1
        end if
       
       
        '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
       
    'Close Xls connection   
    disconnectXLS()
    'Update File-Counter
    intFiles = intFiles + 1
   
    'Debug line
    response.write Ubound(arrControl) & " -> "
   
    'Resset Control array
    ReDim arrControl(1)
    'arrControl(0) = ""
   
    'Debug line
    response.write Ubound(arrControl) & "<br>"
    end if
next

'disconnect to indexDB.mdb
disconnectDB()

'Write Complete in status file
writeStatus intCountAll, "<br>" & intcountValid & " records added in DB<br>Update Complete"
response.write intCountAll & "records processed<br>"& intcountValid & " records added in DB<br>Update Complete"
%>
--------------Kode Slut-------------------------------------------
Avatar billede busschou Praktikant
14. juli 2005 - 17:43 #1
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
Avatar billede busschou Praktikant
14. juli 2005 - 17:46 #2
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
Avatar billede hadaps Nybegynder
14. juli 2005 - 17:46 #3
går denne her ikke ind og tømmer arrayet?:
ReDim arrControl(1)
Avatar billede hadaps Nybegynder
14. juli 2005 - 17:47 #4
det kunne lyde som om det er her jeg skal sætte krafterne ind....
har du et alternativ, vi snakker om 5000+ poster
Avatar billede busschou Praktikant
14. juli 2005 - 17:48 #5
hmm jo du har ret, jeg så forkert, troede du resatte det efter din next :o)
Avatar billede hadaps Nybegynder
14. juli 2005 - 17:50 #6
detalje ;)
du kan se den køre her:
http://80.197.138.2/IO/
(tryk på UpdateDB, og påregne små 2 min)
Avatar billede busschou Praktikant
14. juli 2005 - 17:50 #7
jvnf
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/vblr7/html/vastmredim.asp
Så vil redim preserve netop lave et nyt array og kopiere alle elementerne
Det er klart at det bliver en langsommelig process
Avatar billede hadaps Nybegynder
14. juli 2005 - 17:52 #8
men det som undrer mig mere, er at det tager godt og vel dobbelt så lang tid ved 2. fil, selvom de er ens
Avatar billede busschou Praktikant
14. juli 2005 - 17:52 #9
ja kan godt se det tager tid, men synes da det tager cirka samme tid for fil et som fil to?

Hmm optimering, tænke tænke,
Men kunne måske overveje at benytte scripting.dictionary som jo netop er et "fleksibelt" array
Avatar billede busschou Praktikant
14. juli 2005 - 17:55 #10
hmm så forkert på uret, ja den tager længere
Avatar billede hadaps Nybegynder
14. juli 2005 - 17:55 #11
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?
Avatar billede busschou Praktikant
14. juli 2005 - 17:59 #12
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?
Avatar billede hadaps Nybegynder
14. juli 2005 - 17:59 #13
har du et eksempel på hvordan man bruger scripting.dictionary ?
Avatar billede hadaps Nybegynder
14. juli 2005 - 18:02 #14
argh.. hvad sker her??

-men jo, 2216 -> 1 og 8190 -> 1 er længderne på arrControl før -> efter nulstilling

så der bliver lavet et eller andet, men jeg forstår ikke hvorfor anden gang er så meget længere, når den næste fil er en kopi af nr 1
Avatar billede busschou Praktikant
14. juli 2005 - 18:03 #15
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"
Avatar billede busschou Praktikant
14. juli 2005 - 18:05 #16
det her går galt
ReDim Preserve arrControl(intCountAll)
Du nulstiller ikke din intCountAll
Avatar billede busschou Praktikant
14. juli 2005 - 18:07 #17
Så så snart du er færdig med første fil
Så starter den med at lave en redim preserve med størrelsen på 2216
Avatar billede busschou Praktikant
14. juli 2005 - 18:12 #18
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)
Avatar billede hadaps Nybegynder
14. juli 2005 - 18:13 #19
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
Avatar billede busschou Praktikant
14. juli 2005 - 18:18 #20
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)
Avatar billede hadaps Nybegynder
14. juli 2005 - 18:23 #21
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
Avatar billede hadaps Nybegynder
14. juli 2005 - 18:24 #22
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 ;)
Avatar billede busschou Praktikant
14. juli 2005 - 18:25 #23
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
Avatar billede hadaps Nybegynder
14. juli 2005 - 18:29 #24
jeg vender tilbage, når jeg har et resultat
Avatar billede hadaps Nybegynder
14. juli 2005 - 19:27 #25
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
Avatar billede busschou Praktikant
14. juli 2005 - 19:30 #26
ok så er der lidt at hente på store processer
Det er jo rart at nok at vide :o)
Avatar billede netro Nybegynder
15. juli 2005 - 02:30 #27
Hvis du ønsker at fjerne dit array fra hukommelsen, kan du i stedet for ReDim arrControl(1) bruge Erase arrControl.
Avatar billede hadaps Nybegynder
15. juli 2005 - 09:20 #28
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("")
Avatar billede Ny bruger Nybegynder

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.

Loading billede Opret Preview
Kategori
Kurser inden for grundlæggende programmering

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester