Technical Article

Optimalisering av IO-ytelse for PDF-behandling i gigabyte-skala

\n

Ved behandling av standard flersidige PDF-dokumenter er minne og behandlingstid generelt godt innenfor grensene til moderne maskinvare. Imidlertid, når man får i oppgave å håndtere massive PDF-filer (tenk på gigabyte-skala arkiver som inneholder millioner av objekter) treffer standard analyseringslogikk ofte en ytelsesvegg. Operasjoner som AES-kryptering, som burde være relativt raske, kan plutselig ta minutter.

Den grunnleggende årsaken til denne drastiske nedbremsingen er nesten aldri de CPU-bundne algoritmene som AES eller analysering av tekst. I stedet er den usynlige flaskehalsen I/O-systemkall. La oss undersøke hvordan overgangen fra generisk strømlesing til bufrede direkte fil-API-er kan kutte behandlingstiden med opptil 70 % for massive PDF-dokumenter.

Systemkall-flaskehalsen

I en typisk Delphi-implementering leses et PDF-objekt ved hjelp av en standard TFileStream. For et enkelt objekt ser prosessen vanligvis slik ut:

  1. Les objektoverskriften.
  2. Les objektordboken for å finne grensene.
  3. Kopier de rå objektdataene.
  4. Søk til neste objekt.

Mens dette høres effektivt ut, tvinger underliggende kall til metoder som TStream.GetSize frem flere Seek-systemkall. Videre oversettes lesing og skriving i små biter (for eksempel objektoverskrifter, kryssreferanselinjer og endobj-markører) direkte til tusenvis av individuelle disk lese-/skriveforespørsler.

Hvis du behandler en 2 GB fil med 1,67 millioner objekter, resulterer et tilsynelatende ufarlig mønster med 8 til 12 systemkall per objekt i nesten 20 millioner systemkall. Den konstante kontekstvekslingen mellom brukerrom og kjerneområde ødelegger gjennomstrømningen fullstendig.

Implementering av direkte fil-API-er med skyvevinduer

For å eliminere denne flaskehalsen må filtilgangslaget kobles fra rene TFileStream-operasjoner. Løsningen er å introdusere intelligente lese- og skrivebuffere som opererer på en direkte fil-API-bane, spesifikt designet for PDF-manipulering.

1. Fremoverskuende lesebuffere

I stedet for å lese byte for byte eller objekt for objekt, pakk strømmen din inn i en bufret leser som opprettholder et skyvevindu (for eksempel 1 MB). Når parseren ber om data, gir bufferen det fra minnet. Hvis dataene ikke er i bufferen (en hurtigbufferbom), henter leseren den neste 1 MB blokken fra disk i et enkelt systemkall.

Avgjørende er at denne bufferen må forstå PDF-gjennomgangsmønstre. PDF-analysering krever av og til bakoverrettede søk (for eksempel å lese en utsatt /Length indirekte referanse). Bufferen bør utformes slik at små bakoverrettede søk eller store direkte lesinger ikke unødvendig forurenser eller tømmer det fremoverskuende hurtigbuffervinduet.

2. Skrivebuffere som bare legger til

Skriving er like tungt for systemkall som lesing. I stedet for å skrive objektoverskrifter, strømmer og endobj-markører i separate Write-kall, bruk en skrivebuffer som bare legger til og samler opp utdata i 1 MB biter før den skylles til disk. Bufferen må også pålitelig rapportere sin logiske størrelse slik at forskyvninger for kryssreferanse (XRef)-tabellen beregnes nøyaktig uten å trenge et fysisk Seek på diskstrømmen.

3. Eliminering av doble lesinger

Mange PDF-parsere skanner en blokk med data for å finne et objekts grense, og kaller deretter en "kopi"-rutine som leser den nøyaktig samme blokken på nytt fra strømmen. Ved å sikre at skyvevindusbufferen din kan overføre en direkte minnereferanse eller et utsnitt av allerede leste data, kan du eliminere den sekundære lesingen fullstendig.

Resultatene

I våre interne referansetester med HotPDF og PDFlibPas-komponentene ga introduksjonen av en 1 MB skyvelesebuffer og en skrivebuffer som bare legger til dramatiske forbedringer på en 2 GB fil med 1,67 millioner objekter:

  • Direkte AES-kryptering: Falt fra 152,6 sekunder til 49,4 sekunder.
  • Direkte dekryptering: Falt fra 120,8 sekunder til 42,6 sekunder.
  • Direkte omskriving (Ingen krypto): Falt fra 48,3 sekunder til forbløffende 9,7 sekunder.

Ved å angripe overheaden for systemkall direkte, skalerer gjennomstrømningen forutsigbart med filstørrelse. Dette beviser at når det gjelder massive dokumenter, betyr minnetildeling og I/O-grenser mye mer enn hastigheten til kryptobiblioteket ditt.

Merk: Disse avanserte IO-bufringsteknikkene er implementert i de nyeste versjonene av bibliotekene HotPDF VCL Component og PDFlibPas for å sikre ytelse på bedriftsnivå.

\n
\n