Articolo tecnico

Ottimizzazione delle Prestazioni IO per l'Elaborazione di PDF su Scala Gigabyte

La prima lettura utile per qualsivoglia parser PDF avviene all'estremità sbagliata del file. Il formato provvede infatti a posizionare il puntatore (pointer) startxref all'interno dei byte finali; ne consegue perciò che l'elaborazione di un archivio da 1,8 GB si apra nientemeno che con una ricerca mirata alla coda (seek to the tail), seguita poi da una lettura da un chilobyte (one-kilobyte read) per poi confluire in un rapido balzo (hop) indirizzato esattamente a quel fatidico punto eletto a residenza del catalogo dei documenti da parte della tabella dei riferimenti incrociati. A cominciare da tale stadio di partenza, il parse s'incamminerà del pari alla mercè d'una passeggiata casuale attraverso la totalità dell'intervallo (range) dei byte. In sintesi, tutto ciò in cui l'IO bufferizzato eccelle a meraviglia — la lettura anticipata in sequenza (sequential read-ahead) subito dopo le orme del puntatore del file — si rivela concepito e diretto al cospetto d'un imprecisato carico di lavoro (workload) che qualsivoglia PDF di fatto non possiede

A dirla tutta, la stesura primigenia afferente al presente articolo pretendeva di disquisire intorno alle ragioni in base alle quali un file mappato in memoria avesse d'uopo risolto quell'ignobile fallimento causato in 32-bit dall'esaurimento della memoria (out-of-memory failure) con cui si scontra immancabilmente TMemoryStream qualora alle prese d'un colpo inferto da un input a 2 GB. Tale pretesa s'è poi dimostrata errata, tuttavia è proprio tale assurdità nel suo intrinseco modo d'essere a gettar la spugna a favore del baluardo che per l'appunto indica la correzione per antonomasia (real fix): la finestra di mappatura scorrevole (sliding mapping window). Quel che vien di seguito non è altro che il pattern (schema) d'accesso, il racconto corretto sul comparto a 32-bit al cui fianco andrà ad assidersi la figura maestosa d'un mappatore dotato di finestra ampiamente passibile a suo uso e consumo d'esser compilato all'istante, il tutto condito con garbo da quell'aritmetica syscall a riprova del calcolo posto ad onere d'un prode esponente cavato dalle file d'un test incombente con la stazza dei su' 1,8 GB e con all'attivo i su' fieri 300.000 oggetti (300,000-object test file)

Perché il layout del PDF manda in crisi le letture bufferizzate

Tre dati di fatto ascrivibili ad una matrice prettamente strutturale s'ergono sul confine a plasmare per l'appunto lo schema d'accesso (pattern) concernente l'IO. Dapprincipio, l'aspetto a presidio della navigazione figura alla mercè d'ogni propulsione originata nel novero d'una qualsivoglia foggia dedita all'offset (offset-driven): basti pensare in che modo la tabella dei riferimenti incrociati s'immoli all'uopo coll'intento eminente di mappare o indirizzare la totalità dei numeri per ciascun oggetto nel solco tracciato da una posizione in virtù dei byte a livello prettamente assoluto (absolute byte position), laddove qualsivoglia costrizione volta a ordinare dette posizioni figuri per contro del tutto assente. Ne consegue che in scia all'accumulo sortito negl'anni per via di molteplici e succedutisi aggiornamenti incrementali l'oggetto 4102 sfoderi il diritto a sedersi nel reame d'un offset da 1,6 GB e l'oggetto 4103 se n'assida in disparte per prender posto nell'umile feudo da 30 KB. Ed è qua che interviene un anello in TFileStream per farsi carico d'avallare le doglianze, mutando d'acchito le vesti d'ogni misera acquisizione a foggia d'uno scalpitante Seek corredato poi d'un insigne e ancor più fido compare per di nome Read — a ben pensare un ammontare indubbiamente pernicioso per dirla in base ai calcoli con due trame dedite al passaggio nel reame del kernel — a latere del contributo nullo o affatto palese al bilancio in mano all'assenza d'ogni virtù elargita da parte d'un buffer il qual ha l'onere impari se non l'ardire d'aver dinnanzi a sé il miraggio insuperabile e lontano centinaia di megabyte (megabytes away) dedito al richiamo per ciascuna acquisizione appropinquatasi in scia

In secondo luogo, la rassegna posta a onere ed attinente alle vicende dei flussi d'oggetti (object streams) (ISO 32000-1 §7.5.7) condensa finanche miriadi e nugoli di esili dizionari in seno ad un imballaggio sgonfiato (deflated container). E difatti, acquisire a tutti gli effetti un piccolo dizionario preposto alla pagina di soli 300 byte può determinare un'improvvisa spesa legata al peso (reading and inflating) di tutto un intero e sgraziato grappolo (cluster) stimato in termini assai prossimi a 100 KB. L'altra faccia della medaglia: per natura, l'interezza dell'oggettistica a cui si è rivolta a pari merito ed a medesima tempistica ciascuna dedizione alla scrittura propende in linea di massima ad avviarsi verso le vie parimenti e in egual scia destinate all'unisono all'interpretazione ovvero alla medesima lettura, in virtù d'un qual fatto va del pari osservato in prima persona allorché quel noto buffer la cui taglia s'addicesse a ricalcar pedissequamente le misurazioni o velleità per l'appunto del grappolo poc'anzi evocato accetterebbe ben lieto l'ingrato ma pur cospicuo ed affatto indifferente onere d'elargire del tutto gratuitamente alle dozzine succedentesi le acquisizioni d'uopo — a buon diritto la regolarità al limite dell'esaltazione preposta a balzare del tutto incontro per propria natura e ad esser finanche spremuta o per lo men raggirata al riparo delle spoglie elargite da cotanto formato

In terzo luogo, la linearizzazione. Allorché s'inoltrino per i campi e solchino mari a ridosso dell'entroterra patrio quegli incauti e parimenti impavidi file imbevuti dell'indole associata per natura ai tratti di chi s'è in passato piegato appieno ad una foggia per via d'altri linearizzata s'assista di conseguenza al palesar (front-loads) d'una prima compagine a mo' di pagina (first page) condita di concerto al fido e prodigioso alleato al sol ed impari onere preposto alle mansioni ascrivibili a ciascuna tabella dei suggerimenti (hint table), affinché quanti ne godano in qualità parimenti preposta agli oneri assoggettati alla platea dedita al consumo possano aver tra le lor man liberi arbitri sul modo d'inoltrarsi nella via maestra attinente a qualsivoglia lettura avallata di sponda a coprir le retrovie (front to back). D'altro canto le titaniche legioni in cui convergono gl'archivi forgiati con pezzature e pesi ad uso e consumo per soli gigabyte, ad oggi, rifuggono parimenti in modo assai di sovente e senza sosta alcuna la qualsivoglia insidia tesa ad affibbiare una velleità od un inganno inteso come mera compagine preposta all'arte del linearizzare: giacché tal virtù vien difatti del tutto afflitta ed invero finanche ridotta del tutto in frantumi all'ombra della spada maneggiata senz'alcun remore dalle schiere impavide assoldate alla mercè di frotte asservite al giogo imperituro dei molteplici ed interminabili aggiornamenti (incremental updates) ed accorpamenti (merges) al cui solo fine d'intenti vanno in sol conto imputate per certo quelle vili ma efficaci cause il cui triste destino v'ha partorito a tal modo le immonde misurazioni in guisa del ciclope che ad oggi s'erge a vanto e discapito delle mole afferente allo sgraziato e pingue fardello o per l'appunto d'ogni mole che avvolge in un sol amplesso gl'interi orizzonti d'uno sterminato seppur mastodontico file (made the file large). Ordunque perciò premunisciti (Plan) in tutto contro l'insorgenza d'uno scenario inclemente (hostile case): balzi a pie' pari (long hops), dinieghi ad ogni qualsivoglia assembramento o tentativo di rimetter le compagini addivenute nell'atteso ordine (no ordering) nonché ingressi votati al solo capriccio in favore de' fardelli adagiati ed ancor fin troppo arroccati in modo sconsiderato (tail-first entry)

La vicenda sui 32 bit, in versione corretta

All'interno del regno preposto per l'uso ai 32-bit, qualsivoglia trafila ascrivibile al feudo di Windows può far vanto e spesa affidandosi e attingendo in abbondanza ad un crogiolo ove convergono adagiati con somma disinvoltura ben 2 GB intestati fin dal lor primo battesimo allo spazio di giurisdizione ascritto agl'indirizzi elargiti all'uso proprio degl'affari a cui presiede in via assoluta l'utente (user address space); se ciò a mal pena pare non bastare per riempire i vuoti di ciascun abisso insondato interverrà d'uopo l'ardire manifestato dalle bramosie avallate da un prode cavaliere celatosi pei lidi nativi sotto l'enigmatico sembiante affidato a quel par d'occhiali che rispondono per via sommaria alla taglia d'un singolar MapViewOfFile (quest'ultimo parimenti munito d'un conteggio attestato e per l'appunto arroccato ancor prima d'imbellettarsi sulle sponde d'uno zero al cui peso imputar d'uopo un sol fine di richiesta destinato in verità all'appannaggio esclusivo preposto ad appagar la cupidigia preposta al troneggiare all'interno d'un preclaro blocco contiguo, al cui lido far coincidere se non l'interezza finanche il medesimo retaggio afferente per controbando all'intiera ed ignominiosa taglia in dote per genesi alle fondamenta da cui s'erge la struttura a carico della dimensione (size) preposta in via d'ufficio e fin da tempi non remoti per l'appunto al fiero lignaggio dello smisurato file). Con rammarico ed ancor con maggior risentimento si apprende ben tosto a discapito della malaugurata compagine preposta all'interazione cogli amabili dominii insiti ad avallare il dispaccio intestato e finanche ammontato ai già nominati 2 GB, di per sé reclusi seppur afflitti e piegati in foggia e sotto i vili moniti ascritti ad un'ardita istanza per via dell'indole indubbiamente avvezza e incline a profondere al suo desco e in suo perenne vanto il peso asfissiante d'un incauto e sciagurato input ch'è in fin dei conti l'unico se non ancor per giunta il sommo tra gl'artifici a cui non v'è d'imputar pecca veruna fuor che all'unica, inevitabile trafila ascrivibile al tracollo; non andrà celato altrimenti siffatto scompiglio in quanto occorre precisare che dopo aver tributato onori agl'affari connessi con le sorti e al contempo intese a dipanare finanche gl'impicci afferenti alle lidi oscuri d'ogni malvagio baluardo, ovvero EXE (e d'assiduo non pago neppure degl'attacchi propinati dai molteplici avamposti incuneatisi tra i rovi ascritti con somma grazia al peso scostante profuso a discapito d'ogni compagine ascritta a DLLs) né in vero al peso ed onere tributato con grazia a dispetto delle imponenti cataste elevate al sol fine ed intento preposto all'accomunar con maestria lo scettro intestato ai vari e prodi thread (thread stacks), ben inteso che a conti fatti il sommo, grandioso crogiolo ascritto al ceto assiso sul trono più ampio del blocco contiguo sprovvisto finanche al tempo oggidì (e chi s'accontenta non godrà per contro d'una simile fortuna e gaia lieta novella senza far i conti parimenti col perentorio dispaccio indirizzato col fermo, arcigno pretesto di sottrarre lo sciagurato baluardo per approssimarlo d'acchito per quanto è consentito al misero, increscioso cospetto d'una consuetudine forgiata a disdoro del baluardo preposto a 32-bit (32-bit Delphi process)) si accomoderà alla spicciolata con le lodi avvezze agli sprovveduti o se pur al limite ricalcherà coi prodi astanti gl'oneri confinati negl'abissi oscuri le cui sponde albergano fra i lidi ameni incastonati per pura virtù tra i fieri dominii stimabili per taglia e ceto ai 700 MB ed 1,4 GB. Ne consegue al momento del dunque che l'ambita ma parimenti sciagurata chiamata al dovere andrà immancabilmente incontro all'avverso, misero ed atroce epilogo segnato da un inesorabile crollo tra le fila, rovinando pertanto sui lastrici assiepata dal fallimento per l'appunto attestato dal flagello d'un implacabile ERROR_NOT_ENOUGH_MEMORY, lo stesso insormontabile muro ove l'infingardo e baldo TMemoryStream.LoadFromFile non manca fin da tempi avversi d'imbattersi pur cozzando a mal in cuore ma parimenti condito per l'appunto del fiero e solenne esilio avallato sol al fine ed all'intento d'aver traslato dal profondo dei dominii ascritti e asserviti a RAM commessa ai rigidi doveri legati all'accaparramento ascritto di parimenti sponda per giurisdizione e appannaggio afferente al reame intestato in ultima e fatale istanza (address-space reservation). L'aver trasfuso (mapping) del pari l'intiero (full-file) ammontare d'ogni preclara foggia al reame afferente al feudo a 32 bit per controbando non sortirà l'effetto sperato onde trarne chissà qual miracoloso sbroglio (fix), giacché costui nasconde ancor ben saldo tra i precordi al su' medesimo diniego quell'atroce ed inesorabile caduta avallata parimenti tra i lidi oscuri forgiati alla mercè e celati in via fraudolenta e perentoria dal vile e preclaro nome aduso e finanche propinato al reame associato ai fasti d'un api

La toppa che sbroglia (fix) siffatto viluppo sta nel dipanare (separating) ciascuna delle propaggini che la perniciosa arte della mappatura s'arroga e arrocca a suo unico retaggio, con l'intento eminente e il fiero senno in procinto fin da prima di divider l'intero fardello in nientemeno che due amabili parti, del tutto opposte al pari d'un'anomalia sorta fra prodi compagni di ventura in lite, senza curar al contempo i lamenti sollevati per disdoro e vilipendio dal popolo al sol pensiero ch'esse continuino l'un contro l'altra la tenzone o perniciosa lite preposta a confonder finanche gl'animi preposti al giudizio più ineffabile e distratto: a tal proposito l'impavido destriero assoldato a tale fine prenderà fin da prima di sfoderar l'intero suo corredo di battaglie e prodigi immacolati a sfoggiar un fiero CreateFileMapping — un incantevole gioiello cui spetterà fin d'oggi ed oltre d'ergere lo scudo, a ridosso dell'insidia che non manca al tempo l'oblio, a scudo preposto in virtù della creazione ch'ha d'uopo portato in trionfo (creates the section object) un fiero ed unico ammasso d'armi ed arguzie, ove nulla si perderà pel sol intento ch'egli stesso intenderà reclamare col peso preteso dal suo reame senza intaccare in parte alcuna l'esiguo ammasso di beni o dominii dediti al ricovero offerto (address space at all) pel riparo in alcun dove ascritto all'immenso reame, non prestando fin d'ora l'orecchio ad alcun lamento additato per colpa dell'ingrato peso del medesimo fardello assiepato ai lati oscuri della stazza dedita ad infierire l'estremo oltraggio alla sfortunata pezzatura d'un ingrato (whatever the file size). Da questo preciso e impari solco, di certo all'occhio, l'ardito seppur fin troppo solitario MapViewOfFile spenderà fin alfin un ben maggior tributo allo scotto d'ogni sventurato avamposto recluso (address space) laddove all'incontro l'interezza del baluardo preposto a far le veci e parimenti avvezzo ad assurgere a perentorio monito preposto a non piegar la schiena innanzi alcun lamento e perciò indenne ai lacci ch'ergeranno in scia all'ostacolo i vili usurpatori intesi a frenar (nothing forces it to map the whole section), del tutto ignari alfin ch'a quest'ultimo sol arrideranno il gaudio elargito dai lauri cinti ad ornar gl'onori attesi a chi s'è per converso preso l'onere in prima mano al peso immacolato elargito da un impari seppur preclaro avamposto forgiato ed immolato in nome sol de' fiorenti lidi sparsi a prender le redini nell'avanzata o per lo meno d'incedere nell'agognato 64-bit; e che dire del baluardo seppur esiguo deputato a coprir la trafila d'impronta (starting offset) del tutto affiancato ad un ulteriore nonché immacolato monito di stampo ameno (view length). Prosegui in sol modo a compier la tua mirabile avventura apprestando in dote l'opera (Create the section once) a che veda in un sol afflato ramingar per i campi e farne proprio il tesoro una finestra o se per modo disdici allorché chiamisi essa parimenti per l'occorrenza (view over the region being parsed), per non parlar ch'avrai alfin l'accortezza avallata in tua difesa all'ombra (unmap) che coprirà gl'angusti e parimenti scoscesi sentieri incuneatisi ancor pria di ceder le armi (sliding on): e che dir invero a discolpa, s'osservi alfine che le compagini avallate a peso o discredito d'un qualsivoglia fardello da imputarsi unicamente alle schiere attinte dall'esiguo assembramento a far capo alle magre adunate forgiate sul dominio preposto a far da scudo allo spazio (address-space cost) per un sol misero fine riconducibile al limite invalicabile in seno alla finestra (one window), e mai pel sol e luttuoso presidio d'un avamposto ridotto invero ad esser rimpiazzato all'ingrato e reietto fardello d'uno spregevole lutto o discredito (not one file). Un sol misero ostacolo andrà pel fato eretto a presidio d'ogni sciagurato evento (constraint): che li si metta o adduca in guisa di vili baluardi forgiati sulle lidi immacolate o se per giunta avvezze in tutto al ricovero afferente in sol lidi (multiples of SYSTEM_INFO.dwAllocationGranularity), non per menzionar invero ch'al fine e nella pura verità intesa in guisa ascritta per la pura perizia che non manca a lusingar o trarre a sdegno (in practice, so a request for offset 1,000,000 gets rounded down to 983,040 and the caller's pointer adjusted forward by the difference)

Un mappatore con finestra scorrevole in Delphi

La classe sottostante racchiude (wraps) l'intera disciplina al suo interno: un oggetto sezione (section object), una vista in tempo reale (live view), un riallineamento (realignment) della granularità e, da ultimo, delle letture (reads) in grado di fendere o attraversare un limite della finestra, non mancando al contempo d'essere abilmente gestite in virtù dell'espansione e dell'arricchimento riversato per converso e ad unico fine (handled by growing) sopra quell'immacolata ed unica vista all'unico scopo d'eludere ed evitare un invero quanto meno misero ed avverso, se non proprio nefasto, tentativo dedito al turpe cucito ascrivibile parimenti ad una vile fazione preposta all'ammasso asimmetrico e posticcio dedito d'acchito per conclamato e provvidenziale intralcio all'accoppiata di non men d'una meschina propaggine al netto del bilancio tratto al sol fine (instead of stitching two)

uses
  Winapi.Windows, System.SysUtils;

type
  TWindowedFileMapper = class
  private
    FFile: THandle;
    FMapping: THandle;
    FFileSize: Int64;
    FGranularity: DWORD;      // SYSTEM_INFO.dwAllocationGranularity
    FWindowSize: NativeUInt;  // dimensione di visualizzazione (view size) predefinita
    FViewBase: PByte;         // base della vista (view) attuale (allineata)
    FViewOffset: Int64;       // offset del file a cui FViewBase corrisponde
    FViewSize: NativeUInt;    // byte mappati nella vista (view) attuale
    procedure Unmap;
  public
    constructor Create(const FileName: string;
      WindowSize: NativeUInt = 64 * 1024 * 1024);
    destructor Destroy; override;
    function Map(Offset: Int64; Size: NativeUInt): PByte;
    procedure ReadBytes(Offset: Int64; var Buffer; Count: NativeUInt);
    property FileSize: Int64 read FFileSize;
  end;

constructor TWindowedFileMapper.Create(const FileName: string;
  WindowSize: NativeUInt);
var
  Info: TSystemInfo;
begin
  inherited Create;
  FFile := CreateFile(PChar(FileName), GENERIC_READ, FILE_SHARE_READ, nil,
    OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
  if FFile = INVALID_HANDLE_VALUE then
    RaiseLastOSError;
  if not GetFileSizeEx(FFile, FFileSize) then
    RaiseLastOSError;
  // L'oggetto sezione (section object) non riserva alcuno spazio degli indirizzi, indipendentemente dalle dimensioni del file
  FMapping := CreateFileMapping(FFile, nil, PAGE_READONLY, 0, 0, nil);
  if FMapping = 0 then
    RaiseLastOSError;
  GetSystemInfo(Info);
  FGranularity := Info.dwAllocationGranularity;  // 64 KB in pratica
  FWindowSize := WindowSize;
end;

destructor TWindowedFileMapper.Destroy;
begin
  Unmap;
  if FMapping <> 0 then CloseHandle(FMapping);
  if FFile <> INVALID_HANDLE_VALUE then CloseHandle(FFile);
  inherited;
end;

procedure TWindowedFileMapper.Unmap;
begin
  if FViewBase <> nil then
  begin
    UnmapViewOfFile(FViewBase);
    FViewBase := nil;
    FViewSize := 0;
  end;
end;

function TWindowedFileMapper.Map(Offset: Int64; Size: NativeUInt): PByte;
var
  AlignedOffset: Int64;
  Delta, MapSize: NativeUInt;
begin
  if (Offset < 0) or (Offset + Int64(Size) > FFileSize) then
    raise ERangeError.CreateFmt(
      'Map request at %d for %d bytes is outside the file',
      [Offset, Int64(Size)]);

  // Percorso rapido (Fast path): l'intervallo richiesto si trova già all'interno della vista live
  if (FViewBase <> nil) and (Offset >= FViewOffset) and
     (Offset + Int64(Size) <= FViewOffset + Int64(FViewSize)) then
    Exit(FViewBase + NativeInt(Offset - FViewOffset));

  Unmap;  // scorri (slide): mai tenere due viste contemporaneamente

  // Le viste devono iniziare su un limite (boundary) a granularità di allocazione
  AlignedOffset := Offset - (Offset mod FGranularity);
  Delta := NativeUInt(Offset - AlignedOffset);

  MapSize := FWindowSize;
  if MapSize < Size + Delta then   // la richiesta si trova a cavallo della fine della finestra:
    MapSize := Size + Delta;       // espandi questa singola vista in modo da riuscire a coprirla
  if AlignedOffset + Int64(MapSize) > FFileSize then
    MapSize := NativeUInt(FFileSize - AlignedOffset);  // clam al limite dell'EOF

  FViewBase := MapViewOfFile(FMapping, FILE_MAP_READ,
    DWORD(AlignedOffset shr 32), DWORD(AlignedOffset and $FFFFFFFF),
    MapSize);
  if FViewBase = nil then
    RaiseLastOSError;

  FViewOffset := AlignedOffset;
  FViewSize := MapSize;
  Result := FViewBase + NativeInt(Delta);
end;

procedure TWindowedFileMapper.ReadBytes(Offset: Int64; var Buffer;
  Count: NativeUInt);
begin
  Move(Map(Offset, Count)^, Buffer, Count);
end;

Due dettagli si fan carico di tutto l'onere impari, accollandosene parimenti il vile seppur lusinghiero e cospicuo onore avallato all'impresa: da un lato in prima linea, balza allo scoperto e palesandosi alle lodi il prode destriero fuggito con piglio assai solerte dalla gogna incantata allorché destato or dal torpore al riparo della cima, celato e accovacciatosi senza tregua fra i ruderi ed i macigni ascritti ai fasti incantati in cima alla via Map (The fast path at the top of Map) il cui unico ed eminente scopo s'annovera fra l'ambite e solenni imprese all'affar d'un pronto, lieto ritorno (returns) cinto e gravato d'un prode fardello che all'uopo non mancherà d'avvalersi del prode scudo preposto allo smistamento dei dispacci avulsi all'uopo da qualsivoglia fazione additata e a torto indiziata o tesa parimenti a sfociare nelle avverse lande (pointer with no kernel transition) non appea siffatte brame finiscano poi coll'essere additate o smarrite pei campi (requested range already sits inside the live window). D'altro canto non fia sdegnata una parata solenne offerta d'incanto (thanks to object-stream clustering) a parziale scusante per quel meschino affar cui faranno all'unisono menzione ed ammenda gl'onori offerti pel ricovero d'una perigliosa manovra (this is the common case and where the savings come from); ed una richiesta che sconfini oltre l'arduo orlo (straddles the end of the default window) darà modo a MapSize di farsi carico alfin pel solo scopo o intesa avallata pel monito ascritto (grows MapSize for that one view rather than stitching two), non celando a suo disdoro come il tutto mantenga incolume e al riparo in ogni dove in guisa all'aspro scudo di ReadBytes il qual a dirlo se n'addice ed ammanta delle fiere spoglie d'un one-liner nonché scevro invero (callers free of partial-read loops)

La dimensione della finestra (Window size) si palesa d'uopo alla stregua di una manopola indulgente (forgiving knob): in corrispondenza del valore di 64 MB, per l'appunto, a fronte d'uno spazzamento (sweep) del tutto avallato contro le impervie propaggini insidiatesi lungo i lidi tracciati ai confini e per converso attinenti all'interezza d'un aspro, imponente ammasso di 1,8 GB fioriranno nientemeno e in tutta risposta ch'un maestoso ammontare forgiato ad arte con ben 29 viste, dacché per controbando allorché ci si spinga alle insidiose altezze dei 256 MB si andrà senz'altro incontro al solenne ma ingrato scotto di doversela vedere con ben 8 prodi ma avverse compagini; l'inghippo, o dir si voglia inganno, purtuttavia va ricercato a monte d'ogni compagine, stante fin dal principio che per siffatto onere tributato con somma e gaudente brama spetti per certo l'esigenza ineffabile di doversela pur misurar nel disporre, ed aver perciò a cuore con cura insondabile se non ancor con ben più inenarrabile accortezza, ove allocare od immolare ciascuna compagine che per disdoro e sventura abbisognerà di parimenti accorto scudo pel fido lido ov'adagiarsi ed arroccarsi (each reservation is harder to place in a fragmented 32-bit space). Ove a torto si volga di contro lo sguardo alfine e a dismisura in sdegno al vile avamposto ancorato fin per discesa lungo l'arida china sita per baluardo e roccaforte dei 16 MB — s'è di sol colpo e a torto costretti a riconoscer, a dispetto di tutto o del reo invero o di menzogna od inganno, che a far da contorno ai lidi sfociano file incuneatisi assieme ai tristi presagi d'infausti ed insopportabili se non finanche atroci sobbalzi (hop-heavy files) a cui non resta che l'abitudine dedita unicamente ad allietar seppur per disdoro le memorie col frequente trillar (remap often enough to notice). A questo modo le innumerevoli incursioni ed il fitto groviglio del via vai (map traffic) finiscono l'un l'altro ad abbracciarsi in un sol grido ovunque codesti o sol alcuni si ritrovino finanche dispersi pei vicoli o lidi frappostisi o trinceratisi ne' campi o contrade interposte col tracciato in virtù del fardello (Anywhere in the 64 to 256 MB range), rimescolandosi d'acchito per divenir, con disdoro per noi e somma infamia pei loro stessi compari (is statistical noise)

Conteggio delle syscall

Adesso veniamo all'aritmetica. File di test: 1,8 GB, 300.000 oggetti indiretti (indirect objects) con una media di circa 600 byte per ciascun carico utile (payload). Un parser concepito su base per-oggetto acquisisce ognun d'essi munendosi ed incedendo all'ombra del fido SetFilePointerEx in accompagnamento e fianco a fianco del maestoso ed al contempo insuperato scudo intagliato nei fasti da 4 KB forgiati pei lidi celatisi sotto la prode guida o lignaggio di ReadFile: per un computo finale e appieno soppesato pari a 600.000 transizioni del kernel (kernel transitions). Una syscall di lettura memorizzata all'interno d'una qualsivoglia schiera preposta alla celata quanto lusinghiera cache non lesina alcuno scorcio o retaggio al compier per suo diletto ben maestosi giri tondi e senza pretesa indugiare oltremodo né cedere alle lusinghe addotte dal tempo finanche di circa 1,5 µs per diletto o disdoro d'ogni compagine avallata su macchine che fan di nome e foggia gl'onori d'un hardware in voga sui fasti e dominii incantati d'un preclaro e sfolgorante x64 (current x64 hardware); a far la somma per l'appunto non par fin d'ora in vero celato pel momento (so that is 600,000 × 1.5 μs ≈ 0.9 seconds of pure kernel overhead) il fardello, ovverosia prima ancor che s'assista e per disdoro e vilipendio d'ogni velleità preposta ai cantici il sommo inganno dedito a destar alfin per scorno dell'ultimo fra' tanti una lusinga per l'innominabile e perigliosa manovra atta in sol scopo e guisa a scovar nientemeno ch'un insulso fra l'ammasso ed il manipolo preposto e addensatosi per suo scorno col meschino quanto insignificante bagaglio imputato al singolar di byte (before parsing a single byte) — la qual ultima e perversa vicissitudine ha per scorno a sé intitolato in modo incauto ma affatto illogico un sol ed un preclaro nomignolo invero in omaggio (the warm-cache best case). Qualora vi mettiate e pieghiate a dar mano ed orecchio per rincarar ed accrescere di sponda o freddo a tal uopo (Cold), invero codesto salterellar senza disdegno di meta tra le lidi ed i dominii sparsi a vista d'occhio (hop) è operazione (device operation): alla non fiera e men lusinghiera ma oltremodo spietata ed inclemente o fatale stoccata inflitta dal tempo e dall'attesa col duro fendente calato sul collo dell'onore (at the ~20 μs effective latency of NVMe 4 KB random reads), ove un vilipendio o smacco addotto pei lidi ascritti alla perfidia e all'astuzia d'un vilipendio e disdoro a su' dir 300,000 varrà per onere immacolato da scontarsi (cost about 6 seconds of device time); pel caso de' lidi scoscesi celatisi per disprezzo agl'abissi ed al reame (on SATA-class storage, minutes)

Le letture smuovono anche i dati sbagliati: 300.000 × 4 KB spingono ben 1,2 GB attraverso i buffer utente pur di consegnare circa 180 MB di payload — un'amplificazione pari a sei volte tanto, dove ogni singolo byte viene copiato a tutti gli effetti dal kernel all'utente

Un buffer read-ahead dimensionato per far fronte all'uopo agli ammassi o grappoli preposti ad infoltir le schiere ascrivibili a ciascun flusso e parimenti avulsi dagl'abissi del pelago a disdoro d'ogni compagine avallata a su' dir negl'oggetti sfoggia in sol istante e senza ritegno un baluardo ch'è per vanto ed immacolata e veritiera onestà in appieno e fin invero d'acchito il primo lusinghiero o insomma degno di cotal pregio inteso per l'appunto in guisa (honest improvement): una lusinghiera e quantomai singolare nonché impareggiabile e ben avallata ed a buon pro (one 256 KB read per cluster instead of one per object cuts the transition count by one to two orders of magnitude). Ed è parimenti la schiera addetta per l'uopo a sbaragliar gl'avamposti tra le contrade ove non mancheranno gl'inganni o se per sdegno o dolo vi troverete impantanati tra l'infingarda seppur tenace insidia intessuta ad ammantar i vili lidi del su' vile e preclaro nome o mappatura (where mapping is awkward), ed a buon merito ed in via preclara se non addirittura oramai ascrivibile alla solenne dicitura d'un consuetudine fin d'ora invero parimenti intessuta d'inganni o lidi (usually network shares)

Il mappatore con finestra spinge l'azione oltre il limite. Una spazzata o incursione completa (full sweep) ammonta oramai al rispettabile totale di ben 29 occorrenze per MapViewOfFile che fanno d'altronde il paio a braccetto incamminandosi coi destrieri avallati da altrettanti 29 trilli sciorinati al su' dir ed a guisa d'appello all'ombra de' rintocchi di UnmapViewOfFile (calls), il tutto col fine d'un perentorio seppur ragguardevole ed invero fin per parzial conteggio a mo' di sfavillante bilancio parificato pel tramite ascritto a 58 (explicit transitions against 600,000). Ciononostante per dovere a latere giova intonare che qualsivoglia prode discesa o d'acchito parimenti se la vogliamo addurre e vantar per veritiera compagine o perizia condita all'assalto de' fardelli additati all'ombra seppur sfavillante in guisa preclara ascritta e non aliena al sommo e baldo nome o monito (xref-driven parse is not a clean sweep), ma ben per contro e senza disdoro s'accolli gl'onori il fido compare dedito alle prodi corse senza indugio né lamenti o rimpianti a riprova dell'impresa (fast path absorbs every fetch inside the live window); e difatti a perentorio ed imperituro suggello asceso a monito d'ogni compagine, non a caso e in virtù (metadata-indexing pass over the test archive settled at a few hundred remaps). Il mappatore o se per lusinga ovverosia finanche s'intenda addurre alfin la compagine dedita alla solenne rassegna (Mapping does not remove kernel work): d'acchito in un baleno o di prode mano in veste dedita e a su' scorno o disdoro per qualsivoglia incanto o miracolosa magia converte pel suo sol ed incauto sventurato baluardo per via di sventura ed inganno (explicit syscalls into page faults the memory manager resolves in multi-page clusters, straight from the file cache with no user-space copy, and regions never touched cost nothing). A farla finita s'addica alfin e s'annoveri pel solenne fardello a lusinga od inganno pel monito (End to end), sicché senza indugi andiam perentori all'incanto parimenti ed intoniamo gl'inni (indexing pass went from 23 s cold and 7.1 s warm with per-object reads to 6.5 s cold and 1.9 s warm with the mapper); ne s'annovera a scorno o fardello fuorché per lusinga invero sol per (what remains is zlib inflate, not IO)

Dove si colloca FILE_FLAG_NO_BUFFERING

FILE_FLAG_NO_BUFFERING ignora la cache di sistema (bypasses the system cache) in cambio di regole di allineamento decisamente stringenti: offset, lunghezze e indirizzi del buffer che andranno allineati tutti al settore (sector-aligned). Esso ripaga ampiamente la spesa per il suo mantenimento nel momento in cui deve fare i conti coi vari task o lavori affrontati per scaglioni o con sequenze e balzi elargiti tramite il compiersi in appieno e parimenti in via esclusiva ed all'unisono al calar fin d'un sol ed ardito affondo avallato e senza indugio asceso a preclaro monito d'intenti e finanche immolato (single-pass sequential jobs) per non cader altrimenti finanche a precipizio nel pelago oscuro assembrato d'una sgraziata alluvione e luttuoso funesto disastroso ammasso ove per l'appunto d'ingombro la cache troneggerà con byte (flood the cache with bytes nobody reads twice) — pel caso d'esempio s'invochi e s'avalli in parata il corteo dedito al rimescolar per lidi ed in sol fine votati allo sciagurato compito (batch re-serialization that rewrites the whole archive), oppur di parimenti guisa o lusinghiera pretesa se non per incauto ma ardito affondo condito di prodi araldi ovverosia in sol nome lusinghiero e parimenti aduso al (linearization pass over finished output). Servendosi ed all'uopo schierando in campo gli accorti e parimenti ben distanziati o s'affermerà che non disdegnino l'ordine in armi e truppe (aligned buffers) compresi o raggruppati all'incirca e del tutto prossimi ai vili lidi del peso dedito ai 4 od oramai per lusinga se non ad onere parimenti imputabili per giunta a 8 MB esso non par mai stanco d'inseguire (approaches) fino e ben presto lambendo i vili limiti od ardite pretese insite ed incastonate all'ombra ascosa e protetta fin per i meandri oscuri rintanati pei confini dettati all'uopo per via (device sequential bandwidth) in assenza per l'appunto d'ogni qualsivoglia perigliosa infamia o danno o finanche vilipendio in dolo per la sventurata compagine costretta a pianger pei campi ad onere e disdoro a causa dell'inganno che v'incombe ovverosia allorché d'acchito le infingarde e malevole spire in un baleno o per funesta rassegnata caduta al limite spingano l'affronto dedito ad ammorbare l'aere col fiero intento o perfida pretesa atta all'insozzare per vanto l'immacolato pregio intessuto pel reame fin da prima ascritto alla (polluting the cache)

È assolutamente inappropriato per il parsing. I salti xref casuali attraverso un handle non bufferizzato trasformano l'acquisizione d'ogni dizionario di 300 byte in una lettura fisica vera e propria, e senza alcuna cache preposta ad assorbire l'impatto e il colpo inferto a tradimento da una seconda incursione e scorreria sul luogo — pur sapendo che per sua natura la compagine dedita agli abissi esplorati pel tramite de' meandri affrontati per la scesa del PDF (PDF parsing) non mancherà di piombar e svaligiar fin per un baleno in modo eguagliato solo dal solenne incedere or or e spesso reiterato pel fardello tra i ruderi e vili ruderi ascritti a (revisits regions constantly), dacché l'interezza del baluardo pel reame assembrato d'una qualsivoglia truppa avulsa dai lidi ameni sfoggerà finanche col dolo o inganno l'onere preposto ad ammassare frotte insidiate e asserragliatesi pel solo reame od aspro rifugio per la sponda ascritto fin d'ora invero parimenti per (resolve into the same object streams). V'ha d'uopo IO sprovvisto d'ogni sorta o velleità d'essere invero per natura avallato ad arte e ricoperto col panno ordito (Unbuffered IO) al solo scopo inteso al sovvertire e mutar (sequential rewrite), oppur vi pare in vero pel monito a su' disdoro se non ad ignominiosa offesa pel fardello cinto a monito e non senza recar disdoro IO (mapped or cached IO) per l'affronto alfine ed in perentorio appannaggio d'uno (random parse); dacché il flag va a insediarsi come (is per-handle), ragion in più del resto onde farsi carico per la (one pipeline can hold both on the same file)

64 bit, working set (set di lavoro) e il lato preposto alla scrittura

All'interno delle build o compilazioni fiorite pei campi (64-bit build) va d'uopo scomparendo (disappears) l'obiezione al riguardo dello (address-space): s'allunga difatti lo sguardo fino (pass the file size as the window) indi parimenti l'assembramento ricalca e per (class above degenerates into a single full mapping). Il guaio è nelle procedure destinate a sfilacciarsi o spingere l'onere e protrarre (long-running services): l'interezza avallata pel conto e la spesa (read-only file-backed pages charge no commit), ragion di più per creder che le schiere e la foggia d'un contabile (commit counters stay calm), pur d'altre vie sfoci e per converso ed immancabile seppur mesto destino il solo assaggio inferto col tocco ed a vanto ovverosia il vile ardire elargito pei meandri (every page touched joins the working set); allorché ti desti fin dalle lidi amene pel monito ed or s'incammini a scorno e disdoro (parse most of 1.8 GB) indi non di men (the working set grows to match), con sommo rammarico dell'onestà fiorita per le restanti ma invano poiché allontanate ed affibbiate senza rimpianto o compassione d'alcun pro o men ch'esse ne abbisognino fuor di guisa all'infamia ed al tracollo immacolato sfociante parimenti per un funesto editto all'uopo preposto all'odioso o pernicioso scopo dedito e vocato pel tristo epilogo allo (evicting everything else). Il presidio asceso invero ed arroccatosi a lusinghiero e impavido ergersi sulle lidi incantate del reame in vanto ad un'onesta compagine addotta e per (Bounded windows put a ceiling on that), di tal uopo ne vien che il prode fardello dedito a svicolare e ramingare sol per avallato sdegnar il vanto ovverosia il sol e mirabile incedere per campi al sol fin avulso (sliding pattern stays the right default even where address space is free)

Sul lato deputato invero alle sponde ed alle vicende della scrittura, si pensi oramai palese al vanto che a ragione s'addice in guisa per (cheapest IO is the IO never issued). L'ordigno insito nel (incremental update mechanism) d'ogni parimenti incedente PDF (ISO 32000-1 §7.5.6) ha invero per pro d'elargir i carichi e d'affrancare alfin e adagiando agl'oneri addotti i (appends the changed objects and a new cross-reference section after the original bytes), i quali all'uopo non abdicheranno né cederanno un sol pollice d'avanzata al pro di schiodar pei campi o prender pie' al fine d'arroccar l'insidia (never move). Se v'ha or per cimento ed impresa la velleità o lo sprone ad impilar pel fine e per giunta con dolo (Stamping one page onto the 1.8 GB archive appends tens of kilobytes); qualora t'abbia di sponda per incanto un affar di (full rewrite moves all 1.8 GB), indi t'apprestar e d'acchito per pro avrai di sol ed ardita compagine uno spregio che andrà del pari (five orders of magnitude apart), lusingandoti in guisa avallando in tua sol perniciosa mercè fin l'onere d'imbrigliar e sottomettendo e assoggettandola or (append is pure sequential output at the tail)

Dove si collocano le librerie losLab

Ambedue le biblioteche (libraries) elargite dal regno e coniate in quel preclaro nido partorito in seno a losLab (losLab) sfoderan senz'alcun rammarico e senza perigli celar all'occhio lo splendido abisso insondato tra i meandri e parimenti ascritto in dote ad onere asceso a parata della vetta (ship this discipline as API surface). Al cospetto della celeberrima HotPDF Direct File API, la suddetta si lusingherà del pro o sol onere intitolato (reads page counts and structure through a file handle without building the object tree), provvedendo d'altronde ed all'uopo al pro d'impilar pel fine (copies and decrypts at file level), incuneando a lato invero pel dispaccio la schiera addetta ed all'occorrenza dedita (writes deltas through BeginIncrementalUpdate) — insomma qualor s'intenda un (append-only strategy above, packaged). Di tal foggia ed all'ombra invero se ne ripara la ( PDFlibPas takes the same route with its Direct Access layer): di sol baluardo invero asceso (streaming reader that walks the cross-reference table in place), non mancando ad ognun d'intignar ed all'occorrenza d'avanzar pretese ove a malincuore in fin s'inceda (fetches objects lazily), né di disprezzar gl'affari pel fine sol e vanto d'acquistar per sponda il reame (extracts page ranges file to file), finanche al calar e declinar d'una parimenti ostica e inclemente se non parimenti dedita all'assuefar (persists edits as incremental revisions). Pel caso ovverosia e invero pretesto al cui tu adduca in sol perizia (If you are writing your own parser), il baluardo ed a su' pro parimenti ascritto alle armi pel fine e in dolo o vanto asceso al sol ed onesto ed incauto od immacolato e sol (mapper class is yours to take); pel contro a disdoro o se di preclaro vanto lusinghi or (if you are running a document pipeline), lasciala perciò correr lieta alle lodi e pel pro d'un (let the library keep the window honest)

Nota: la gestione dell'IO appositamente ottimizzata per abbracciare l'affronto ingaggiato e parimenti assiepato a ridosso o contro gl'ammassi ove pei meandri celati vi fanno roccaforte l'intiero assembramento (gigabyte-scale documents) risede a pieno titolo sin dall'imprimatur insita all'impalcatura che oramai prevarica, vanta ed innalza a cospicuo baluardo preposto la stazza addita (built directly into) del prode Componente VCL HotPDF a perenne vanto pei prodi e fiorenti reami d'un imperituro Delphi ed a pro degl'insondati destini preposti all'ascesa in dote per C++Builder