18. juni 2002 - 17:29Der er
39 kommentarer og 1 løsning
"SetTextBuf" hjælper ikke meget - er der en bedre løsning
Jeg skal lave en applikation, som kan gennemlæse store tekstfiler(o 300MB) så hurtigt som muligt. Jeg skal kontrollere hvad der står på alle linier af filen.
Hvordan gør man det bedste(hurtigst)?
Jeg læste at man selv kan definere en buffer ved hjælp af "SetTextBuf", og herefter skulle læsningen bliver hurtigere. Dette er afprøvet og det gav ikke meget.
Jeg har også forsøgt at læse større bider af filen med "BlockRead" og derefter gennemgå disse bider. Dette viste sig at være endnu værre.
Er der nogen der har en ide om hvordan dette gøres bedst(hurtigst)?
function FindMig(HvadSkalJegFinde, FilNavn: String): Boolean; var F: File; S: String; begin FileMode := 0; AssignFile(F, FilNavn); Reset(F, 1); Result := False; while not Eof(F) do begin ReadLn(F, S); Result := Pos(HvadSkalJegFinde, S) <> 0; if Result then Break; end; CloseFile(F); end;
Du finder nok ikke noget langsommere end TekstFiler, men jeg kan vamt anbefale BlockRead som du (af "ukendte årsager") ikke er glad for. Når du bruger BlockRead så er der 2 ting der er vigtigt - Brug en relativ stor buffer (4, 8, 16, 32 eller 64 KByte) - Når du kalder Reset så kan man vælge at overføre en RecSize, sæt ALTID denne til 1 (F.eks. "Reset(F, 1);"). Hvis du ikke gør så er RecSize 128 og hvis du skriver "BlockRead(F, Buffer, 4096, Res)" så læser du rent faktisk godt 500.000 Kb i stedet for kun 4 KB (noget der kan få BlockRead til at "virke langsom").
En helt anden ting er selve søgningen. I dette sammenhæng efterlader Delphi's egen POS meget at ønske. En Boyer-Moore algoritme kan således nemt "hægte" Delphis egen pos og gøre en søgning indtil flere gange hurtigere. Borrisholt har "noget kode" til dette formål så muligvis han melder sig på banen med dette !?
Tekstfilen består af ekstremt mange relativt korte linier(Tags). Eks. :010: :202: evt. tekst o.s.v...
Jeg skal finde antallet af bestemte tags i meget store tekstfiler(300MB eller mere). Jeg skal evt. også gemme positionen på disse tags i tekstfilen, således at jeg kan kopiere en del af tekstfilen over i en anden efter gennemlæsningen.
På nuværende tidspunkt tager det ca. 2 minuter bare at læse en 300MB fil igennem uden at behandle linierne(Altså med ReadLN). Som jeg før har omtalt, så har jeg også prøvet at benytte "BlockRead", som korrekt gør læsningen hurtigere med den rigtige bufferstørrelse. Dette gør dog at jeg nu har en buffer, hvor jeg først skal finde ud af hvor linien stopper og derefter skal undersøge om denne linie indeholder det jeg leder efter. Dette gør det mere tungt end ReadLN.
Så det jeg leder efter er måske en hurtig metode til at søge i en Charbuffer?
God arbejds-fordeling, du klare opgaven jeg "score fortjensten". Nu vi er igang vil du ha' mit Kontonummer således jeg også kan få udbetalt din løn ? ;-)
Løsningen for mig er nok at udvide "file_Search" lidt, således at den kan håndtere en given buffer ad gangen. Evt. ved at lave en "LoadBuffer()" og en "UnLoadBuffer()". På denne måde kan selv kontrollere hvor meget den skal flæske igennem ad gangen.
Alternativet er at "File_Search" selv skulle kunne splitte filen op og håndtere det hele selv, men det er nok lidt mere problematisk.
Hvis du splitte filen op i "flere bidder", så skal du være ekstra opmærksom på de stedet hvor du deler filen. Med andre ord hvis du leder efter "Hest" kan du risikere at "He" står i den ene buffer og "st" i den anden. Du er således nødt til at "gøre lidt gymnastik" for at fange disse situiationer.
borrisholt> Ingen tvivl om at den er nem at fange, jeg ville bare påpeje at man lige skal være opmærksom på "problemer" (det vil jo vare katestrofalt at dele hesten) :-)
Man kan vel også bare hoppe "Length(Pattern)-1" tilbage før man læser næste chunk. Således kan man være sikker på at man ikke registrerer et "hit" i hver buffer eller overser det.
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.