Perl5 som datavetenskapsspråk
Serieintroduktion – Post 0 av N
Det här inlägget är det första i en serie som dokumenterar samutvecklingen av en vektor-databasmotor (VDBE) skriven helt i Perl5 + PDL. Senare inlägg går igenom varje komponent i den motorn; den här sätter scenen. Den viktigaste drivkraften för denna serie är INTE att du dumpar din VDBE eftersom jag inte gör några prestandakrav, men för att visa hur man kan använda Perl för att uppnå i stort sett allt du kan uppnå med något annat språk, men smartare!
Innehållsförteckning
- Innehållsförteckning
- 1. Varför Perl5 för datavetenskap?
- 2. Perl Data-Type System – Styrkor och Cache-Era-gränser
- 3. Ange PDL: Starkt typade N-dimensionella uppställningar
- 4. Typjämförelse: Perl, PDL och R sida vid sida
- 5. Vägkarta: Vad resten av denna serie täcker
- Post 1 – Serialisering och I/O:
VectorIOmodul - Post 2 – Simulera en vektordatabas
- Post 3 – Riktmärkning:
timing_DBModul - Post 4 — K-Means-klustring med
PDL::Stat::Kmedel - Inlägg 5 — Mini-Batch K-Means: Skalning till stora datamängder
- Inlägg 6 — Sökning efter index för inverterad fil (IVF)
- Post 7 – Validering mot R: Numerisk korrekthet och korsspråkiga pipeliner
- Post 1 – Serialisering och I/O:
1. Varför Perl5 för datavetenskap?
När dataforskare diskuterar språkval konvergerar konversationen snabbt på Python, R eller Julia. Perl5 får sällan en plats vid bordet - men det bär en övertygande uppsättning egenskaper som förtjänar en andra titt. Dessa egenskaper har inte förändrats väsentligt genom åren (Perl5 har alltid varit så!), men om inte Du har blivit utsatt för språket och lärt dig att uppskatta dess tercity, rationalitet, flexibilitet, uttrycksfullhet och faktiskt använt det för att driva ditt arbete framåt., du skulle inte veta att dessa funktioner inte bara kommer gratis med Perl5, men kan hjälpa dig att driva dina projekt framåt.
Ubiquity och driftsättning utan installation
Perl5 levereras som standardkomponent i praktiskt taget alla UNIX-liknande operativsystem – Linux-distributioner, macOS, BSD:er och många inbäddade Linux-miljöer innehåller alla en fungerande möjligen Binär ur lådan. Python har gjort inbrytningar här, men det är fortfarande vanligt att hitta huvudlösa servrar, nätverksenheter eller HPC-inloggningsnoder
där Perl är närvarande och en full Python stack är inte. En datapipeline skriven i Perl kan köras dag ett utan en conda miljö, a venveller en container.
Portabilitet från datacentret till kanten
Samma skript som analyserar en terabyte-datamängd på en 256-kärnig HPC-nod kan, med mindre konfigurationsändringar, köras på en Raspberry Pi, en IoT-gateway eller en inbäddad styrenhet. Perl’en binär distributionsmodell och låga administrationskostnader gör den till en äkta “skriv en gång, kör var som helst” Språk i miljöer där Python’s tolk overhead eller Julia’JIT uppvärmningstid skulle vara oacceptabelt.
Om du planerar att distribuera var som helst och everywhere Perl5 är ditt självklara val.
Ett arv byggt på text- och datamunging
Perl har utformats från grunden för textbearbetning, reguljära uttryck och “lim” arbete mellan systemkomponenter. I praktiken domineras vetenskapliga datapipeliner inte av numerisk beräkning utan av dataskryptering: läsning av heterogena filformat, rengöring av röriga poster, koppling av datamängder från olika källor och dirigering av resultat till nedströmskrävande komponenter.
Perl’regex-motorn är fortfarande bland de mest kraftfulla tillgängliga, och en-liners kan utföra datarengöringsuppgifter som skulle kräva hjälpbibliotek på andra språk.
Om du är inom området vetenskaplig databehandling kan du ha stött på begreppet *arbetsflödeshanteringssystem *och *reproducerbar forskning *. De är båda beroende av exekveringen av heltäckande datatransformeringar och arbetsflöden för att eliminera de manuella, felbenägna och tråkiga peka och klicka-aktiviteter som analytiker och forskare måste göra för att omvandla sina data till insikter respektive slutsatser.
I denna modiga nya värld, Perl5’s rika historia gör det möjligt att lysa både som en komponent i arbetsflöden, eller som ett applikationsspråk som implementerar dessa arbetsflöden.
CPAN: ett stridstestat modulekosystem
Det omfattande Perl Archive Network (CPAN) är värd för över 200 000 moduler över alla tänkbara domäner. Medan datavetenskapserbjudandena inte är nästan lika omfattande som Python, finns de grundläggande komponenterna för dedikerade byggare där:
PDL (Perl Data Language) – vektoriserad numerisk databehandling med starkt typangivna N-dimensionella matriser (täckt på djupet nedan).
PDL::Stats – beskrivande statistik, regression, klustring (k-means, mini-batch k-means) och mer, byggd ovanpå PDL ndarrays.
AI::MXNet, AI::TensorFlow – djupinlärningsbindningar.
Statistik::Regression, Statistik::Beskrivning — klassisk statistik utan PDL-beroendet.
Text::CSV, Kalkylblad::XLSX, Data::MessagePack, Sereal — serialisering med hög prestanda och I/O.
DBI + dussintals databasdrivrutiner - SQL-åtkomst till alla större RDBMS.
MCE (Many-Core Engine) – strukturerad parallellitet för arbetsbelastningar med delade och distribuerade minnen.
Inline::C, Inline::CPP — bädda in C- eller C++-kod direkt i en Perl-källfil; kompilatorn anropas transparent första gången skriptet körs, vilket gör det trivialt att släppa prestandakritiska kärnor i ett annars rent-Perl-program utan ett fullständigt XS-byggsystem.
FFI::Platypus — anropsfunktioner i ett delat bibliotek (
så/.dylib/.dll) från Perl utan att skriva en enda rad med XS- eller C-limkod. Platypus stöder alla C-ekvivalenta typer, strukturer, återuppringningar och nedstängningar, och är det moderna sättet att binda Perl till BLAS, LAPACK, HDF5 eller något annat ursprungligt bibliotek.
Modern Perl är inte din farfar’s Perl
Funktionerna nedan är hämtade direkt från den officiella releaseinformationen (perl5360delta, perl5380delta, perl5400delta) och organiseras av den utgåva där de uppnådde status stabil eller först introducerades. Endast funktioner som är relevanta för arbetsbelastningar inom datavetenskap och vetenskaplig beräkning markeras.
Perl 5.36 – maj 2022
Använd v5.36— funktionspaketet aktiveras nu automatisktanvänd varningarochanvänd strikt. Det inaktiverar ocksåindirektmetod-call syntax ochflerdimensionellhash-key simulering, vilket eliminerar två vanliga källor till subtila buggar.Namngivna subrutinsignaturer (stabil sedan 5.36; experimentell sedan 5.20) – funktionsparametrar deklareras nu med namn, med valfria standardvärden. Den
//=och||=Operatorer med standardvärden har lagts till i signaturer i 5.38, vilket tillåter standardvärden som utlöses påofördelaktigeller falskhet respektive:
use v5.36;
sub clamp ($val, $lo = 0, $hi //= 1) {
$val < $lo ? $lo : $val > $hi ? $hi : $val;
}
isaklassinstansoperator (stabil sedan 5.36; introducerad i 5.32) —$obj isa "ClassName"returnerar ett booleskt värde; renare änref($obj) eq "ClassName".inbyggdmodul (stabil sedan 5.40; experimentell sedan 5.36) — lexikalt importabla funktioner som är inbyggda direkt i tolken. Det stabila 5.40-paketet innehåller bland annat:tak,våningheltalsavrundning utananvänd POSIX.trimma— ta bort inledande/avslutande blanktecken från en sträng.indexerad- parar varje element med sitt index; den idiomatiska följeslagaren till flera värdenföröglor (se nedan).sant,falskt,is_bool— Booleska sentineltyper; serialiserare kan nu avge JSONsant/falsktsnarare än1/0.försvaga,väcka,is_weak— Kontroll av referensantal för att bygga dubbelriktade datastrukturer utan minnesläckor.välsignad,returtyp,adresseraReferensintrospektion.
Tabell boolesk spårning (5.36) – skalärer skapade som booleska värden (t.ex.
!!1) behåller nu sin booleska karaktär genom tilldelning, vilket möjliggör tillförlitlig typmedveten serialisering till JSON och MessagePack.Multivärde
förloopar (stabil sedan 5.40; experimentell sedan 5.36) Iterera över par eller N-tupler utan manuell indexaritmetik:
use v5.40;
use builtin 'indexed';
for my ($i, $val) (indexed @scores) { ... } # index and value
Eller hämta flera värden samtidigt
use v5.40;
for my ($val1, $val2, $val3) (@scores) { ... }
skjutsblock (experimentellt sedan 5.36) – ett omfattnings-exit-skydd som kör rensningskoden villkorslöst när ett block avslutas, antingen normalt eller via undantag – en naturlig ersättning för destruktorbaserade omfattningsbevakningsobjekt och ett viktigt mönster för resurshantering i datapipeliner.
Perl 5.38 – juli 2023
PERL_RAND_SEEDmiljövariabel (5.38) – ställer in den här variabeln innan en körning gör varjerandsamtal (utan uttryckligsrand) producerar samma sekvens, vilket möjliggör **reproducerbara **stokastiska algoritmer - simuleringar, slumpmässig provtagning, Monte Carlo-metoder - utan att ändra källkoden.socialklass/slagfält/metodsyntax (experimentellt sedan 5.38) – ett specialbyggt, lexikaliskt begränsat objektsystem som inte kräver någotvälsignaoch@ISAeller någon CPAN-modul. Användbart för att definiera typangivna värdeobjekt, t.ex. datauppsättningsrader, modellparametrar eller pipelinesteg:
use feature 'class';
no warnings 'experimental::class';
class Vector2D {
field $x :param;
field $y :param;
method magnitude { sqrt($x**2 + $y**2) }
}
my $v = Vector2D->new(x => 3, y => 4);
say $v->magnitude; # 5
Perl 5.40 – juni 2024
försöka/fångaundantagshantering (stabil sedan 5.40; experimentell sedan 5.34;någon gångblock tillagt i 5.36) – strukturerad undantagshantering är nu en huvudspråkfunktion; ingen CPAN-modul krävs:
use v5.40;
try {
my $result = load_and_process($file);
}
catch ($e) {
warn "Pipeline error: $e";
}
finally {
close_resources(); # runs whether or not an exception was thrown
}
(Försök::Tiny / Funktion::Compat::Försök behövs endast vid målinriktning av perls äldre än 5,34.)
Multivärde
förloopar (stabil sedan 5.40) — se 5.36 posten ovan; de tog examen från experimentell till stabil i denna utgåva.inbyggt::infochinbyggt::nan(experimentell sedan 5.40) — typade flytande-punkt oändlighet och Not-a-Number konstanter, eliminera9**9**9eller POSIX-hack i numerisk kod.^^logisk XOR-operator (5.40) – slutför den logiska operatoruppsättningen med medelhög prioritet (&&,||,^^); praktiskt för booleska maskoperationer.Använd v5.40importerar inbyggda funktioner – utöver att aktivera funktionspaketetAnvänd v5.40importerar även motsvarandeinbyggdversionspaket, vilket gör alla stabilainbyggd:Funktioner tillgängliga som kortnamn utan separatanvänd inbyggdsats.
Långvariga funktioner (före 5.36)
sägaochdelstat(sedan 5.10) —sägaärtryckamed en implicit ny linje;delstatförklarar en lexikal som kvarstår över anrop av dess omslutande sub (en lätt primitiv memoar).Referenser och stängningar i första klass – anonyma del-, stängnings- och referenskonstruktioner är grundläggande och har varit stabila sedan Perl 5.
använd konstanteller CPANSkrivskyddadModul för namngivna konstanter.Skrivskyddadgenomdriver djup oföränderlighet somanvänd konstantgör det inte.
Kombinerad med perlbreiska eller plenarförsamling för versionshantering och kartong För reproducerbara beroendeögonblicksbilder ser ett modernt Perl-projekt ut och känns som en förstklassig programvaruutveckling.
Ärliga begränsningar
Inget fall för Perl är komplett utan ärlighet om var det faller kort:
Visualisering – Perl har ingen motsvarighet
ggplot2ellermullvad. Plottningar kräver vanligtvis ett externt anrop till R, gnuplot eller ett webbbibliotek. Ibland kan denna svaghet bli en verklig styrka, så att man kan använda Perl5 som applikationsspråk som orkestrerar och förbättrar de andra aktörerna.Gemenskapens drivkraft - Datavetenskapssamhället har konvergerat på Python och R. Att hitta färdiga handledningar, Stack Overflow-svar och medförfattare är svårare.
Objektorientering - utan Älg/Moo är OOP-modellen utförlig; med dem lägger det till ett beroende. Den nya
socialklassfunktionen kan lösa några av dessa problemTypsäkerhet i stor skala — Kärnspråket’s dynamiska skalärer gör stora, samarbetande numeriska kodbaser svårare att resonera om (se nästa avsnitt).
2. Perl Data-Type System – Styrkor och Cache-Era-gränser
Kärna perl-typer
Perl’s grundläggande datamodell centrerar på tre konstruktioner:
| Konstruktion | Sigil | Vad den håller |
|---|---|---|
| Skalär | $ |
Ett enstaka värde: tal, sträng, referens eller ofördelaktig |
| Uppställning | @ |
En ordnad lista över skalärer, indexerade efter heltal |
| Hash | % |
En osorterad samling skalära värden som anges med sträng |
Allt annat - objekt, förslutningar, komplexa datastrukturer - byggs från dessa tre primitiver via *referenser *(\@array, \%hash, nedsänkt { ... }).
Denna modell är extremt flexibel. En enskild array kan innehålla heltal, flyttal, strängar och kapslade referenser samtidigt. Den flexibiliteten är precis vad som gjorde Perl till det dominerande systemadministrations- och webbskriptspråket i två decennier.
Problemet med cachehierarkin
Moderna processorer uppnår toppdataflöde endast när data flödar genom cachen L1/L2/L3† i stora, sammanhängande block - en egenskap som kallas spatial locality. Perl-matriser tillhandahåller inte detta. Under huven är en Perl-matris en C-matris med pekare till högallokerad skalär (SV) strukturerna. Varje skalär har ett referensantal, en typtagg och utfyllnad - vanligtvis 24-56 byte per skalär på en 64-bitarsversion. Iterera över en miljon-element Perl array innebär därför en miljon pekare avreferenser spridda över heap, vilket ger en cache-miss mönster som helt förnekar hastighetsfördelen med moderna SIMD rörledningar.
En konkret konsekvens: en punktprodukt av två 1 000-elementvektorer skrivna i ren Perl är ungefär 100-1000 × långsammare än motsvarande operation på ett par PDL-float ndarrays, som upptar två platta minnesregioner på 4 000 byte som passar bekvämt i L1-cachen.
Jämför med R
R upptar en märklig medelväg. Liksom Perl är det ett dynamiskt, tolkat språk - variabler är otypade behållare, funktioner är förstklassiga värden och den interaktiva REPL är den primära utvecklingsmiljön. R har även direkta analoger till Perl’s tre kärntyper:
| Perl koncept | R analog |
|---|---|
$skalär |
längd-1 atomär vektor eller skalär-i-lista |
@array |
lista() |
% hash |
namngiven lista() |
Referens (\@arr) |
R använder inte uttryckliga referenser; copy-on-modify semantik i stället |
Men R’typen s workhorse, dvs. den atomiska vektorn har ingen enkel Perl-motsvarighet. En R-atomvektor är ett sammanhängande, homogent typat minnesblock - exakt den layout som en CPU-cache belönar. Varje inbyggd skalär i R är faktiskt en längd-1 atomär vektor; det finns ingen “blottad skalär” Utanför atomvektorer.
Detta designval innebär att R-kod naturligt fungerar på vektorer av miljontals dubbletter med BLAS-nivå genomströmning, utan att användaren skriver en enda slinga eller allokerar en speciell “uppställning” objekt.
R’atomtyperna är:
| R atomär typ | Lagring | C ekvivalent |
|---|---|---|
logisk |
4 byte/element | heltal (Omdirigerad från NA Sentinel) |
heltal |
4 byte/element | int32_t |
fördubbla |
8 byte/element | fördubbla |
komplex |
16 byte/element | _Komplex dubbel |
skrivtecken |
pekare till CHARSXP | tecken * (internerad) |
rå |
1 byte/element | uint8_t |
R definierar också högre strukturer byggda på atomvektorer:
- matris — en 2-D atomär vektor med en
dimmaattribut - array – en N-D-atomvektor med en
dimmaattribut - data.frame — en namngiven lista över atomvektorer av samma längd; lingua franca av
tabelldata i R. - faktor – en heltalsvektor med en
nivåerattribut; kodar kategoriska data.
Lärdom: R’beräkningsprestanda när den används i statistiska och datavetenskapliga applikationer flödar direkt från dess angränsande atomvektorer. Perl’motsvarande väg till prestanda är en förlängning (som också är en fristående matris som miljö), Perl Data Language PDL.
3. Ange PDL: Starkt typade N-dimensionella uppställningar
Perl-dataspråk (PDL, pdl.perl.org) utökar Perl med *ndarrays *(N-dimensionella matriser): sammanhängande, starkt skrivna minnesbuffertar som ser ut och känns som förstklassiga Perl-objekt.
use PDL;
# A 1-D float ndarray — 4 bytes × 5 elements in one contiguous block
my $v = float( 1.0, 2.0, 3.0, 4.0, 5.0 );
# A 128-dimensional random database of 1000 vectors — all in cache-friendly memory
my $db = random( 128, 1000 ); # double by default
# Dot product of every DB vector against a query — a single BLAS call
my $scores = $db x $query->transpose;
PDL-primitiva typer
PDL visar hela paletten med numeriska C-typer som förstklassiga konstruktorer:
| PDL typ | Byte | C typ | Konstruktör |
|---|---|---|---|
byte |
1 | uint8_t |
byte(...) |
kortslutning |
2 | int16_t |
kort(...) |
kohort |
2 | uint16_t |
Om oss(...) |
hög |
4 | int32_t |
lång(...) |
indx 4 eller 8 |
ssize_t |
indx(...) |
|
lång |
8 | int64_t |
långa(...) |
flyta |
4 | flyta |
flyta(...) |
fördubbla |
8 | fördubbla |
dubbel(...) |
toalett |
8 | _Komplex flyttal |
Cfloat(...) |
dubbel |
16 | _Komplex dubbel |
dubbel(...) |
Gängning och SIMD
En av PDL’s mest distinkta funktioner är *implicit trådning *: operationer sänds automatiskt över extra dimensioner, vilket eliminerar explicita slingor i användarkoden och delegerar inre slingor till optimerade C- eller Fortran-kärnor. Kombinerad med set_autopthread_targ(N), PDL parallelliserar automatiskt oberoende segment över N OS-trådar – utan att användaren skriver en enda vägskäl eller Tråd::Kö ring.
Felaktiga värden
PDL har ett inbyggt koncept med dåliga värden (PDL::Fel), direkt analogt med R’s Ej tillämpligt. En ndarray kan flaggas som “medveten om dåligt värde”, och PDL-åtgärder sprider ondska korrekt genom aritmetik, statistik och I/O.
4. Typjämförelse: Perl, PDL och R sida vid sida
Tabellen nedan kartlägger varje vanlig R-typ till sina närmaste Perl- och PDL-motsvarigheter, och belyser var de tre språken är överens, skiljer sig åt eller kompletterar varandra.
| R typ | Perl ekvivalent | PDL ekvivalent | Anteckningar |
|---|---|---|---|
fördubbla (längd-1) |
$x = 3,14 (skalär) |
dubbel(3.14) — form () R har ingen skalär; allt är en vektor |
|
heltal (längd-1) |
$n = 42 (skalär) |
lång(42) |
|
logisk (längd-1) |
$flag = 1 / $flag = 0 |
byte(1) Perl använder sanningsenlighet; PDL använder 0/1 byte |
|
fördubbla vektor |
@arr = (1.1, 2.2, 3.3) |
dubbel (1.1, 2.2, 3.3) |
PDL: sammanhängande; @arr: pekaruppställning |
heltal vektor |
@arr = (1, 2, 3) |
lång(1, 2, 3) |
|
logisk vektor |
@flags = (1, 0, 1) |
byte(1, 0, 1) |
|
komplex vektor |
— (ingen inbyggd) | dubbel(...) Perl behov Matematik::KomplexPDL har inbyggt stöd |
|
skrivtecken vektor |
@strs = ('år','b)') |
— (inte numeriskt) | PDL används endast på siffror |
rå vektor |
pack('C*', @bytes) |
byte(...) |
|
Ej tillämpligt |
ofördelaktig |
Dåligt värde i ndarray | PDL dåliga värden sprids som R’s Ej tillämpligt |
NULL |
ofördelaktig i förteckningssammanhang |
— | |
lista |
@array eller referens \@array |
— | |
namngiven lista |
% hash eller \%hash |
— | |
matris (2-D) |
array-of-arrays @aoa |
2D ndarray pdl([[...],[...]]) |
PDL: kolumn-huvud; R: kolumn-huvudämne |
uppställning (N-D) |
kapslade referenser | N-D ndarray $x->reshape(...) |
|
data.frame |
% hash av @arrays |
2-D ndarray (numeriska kolon) + Perl hash (blandad) | Inga enskilda PDL-typkartor exakt |
faktor |
hash söktabell + @indices |
hög ndarray + perl @levels uppställning |
|
miljö |
% hash eller paketnamnrymd |
— | |
funktion / stängning |
nedsänkt { ... } / stängning |
— | PDL PP definierar sammanställda kärnor |
Objektet S3/S4 |
välsignad referens + metodutskick | PDL objekt (välsignad ndarray) | PDL objekt är förstklassiga Perl objekt |
Viktiga insikter
För rena numeriska, homogena data (vektorer, matriser, tensorer), är PDL-ndarrays och R-atomvektorer funktionellt likvärdiga och jämförelsevis effektiva.
För heterogena tabelldata (blandade typer, strängkolumner, faktorer), R’s
data.frameär mer ergonomisk; Perl använder vanligtvis en hash av arrayer eller en dedikerad modul somData::ramellerPDL::IO::CSV.För text, oregelbundna strukturer och systemlim, Perl’De ursprungliga typerna är överlägsna både R och Python.
Kombinationen av Perl+PDL ger därför union av vad R erbjuder som ett statistiskt språk och vad Perl erbjuder som ett systemspråk - på bekostnad av en brantare inlärningskurva och mindre out-of-the-box och uppriktigt sagt begränsad statistisk verktyg.
Kombinationen av Perl+PDL+R (med den senare som komponent, eller instrumentaliserad via Perl)
5. Vägkarta: Vad resten av denna serie täcker
Den här serien dokumenterar konstruktionen av en vektordatabasmotor byggd i Perl5 + PDL från grunden. Vektordatabaser bygger på moderna RAG-pipeliner (hämtningsförstärkta generering), semantisk sökning och rekommendationssystem närmaste granne. Att genomföra en av de första principerna är ett utmärkt fordon för att demonstrera PDL’s numeriska förmågor tillsammans med Perl’Styrkor med systemprogrammering.
Katalogen som samutvecklas tillsammans med dessa inlägg innehåller följande komponenter, som var och en kommer att vara föremål för en eller flera dedikerade inlägg som kommer att referera till filer i ett dedikerat arkiv.
Post 1 – Serialisering och I/O: VectorIO modul
Fil: VectorIO.pm
Motorn lagrar vektorer som packade binära blobbar inuti MessagePack nyttolaster. Detta inlägg täcker:
- Designa en modul med en ren
Exportör-baserat offentligt API underAnvänd v5.40. - Valideringshjälpmedel som upprätthåller schemanättighet vid systemgränser.
Post 2 – Simulera en vektordatabas
Fil: simulate_vectorDB.pl
Innan vi kan söka i en databas behöver vi en. Det här inlägget visar:
- Genererar reproducerbara slumpmässiga float vektorer med
PDL::slumpmässig. - Använda
GetOpt::Långför ergonomisk CLI-tolkning. - Skriva en
--frö-styrd simulering som producerar identiska databaser över körningar - viktigt för benchmarking.
Post 3 – Riktmärkning: timing_DB Modul
Fil: timing_DB.pm
Prestationsanspråk kräver mätning. Detta inlägg introducerar:
- En återanvändbar Perl benchmarking sele byggd på
Tid::HiRes. - Metodik för rättvisa väggklockjämförelser mellan Perl/PDL och R-implementationer.
- Tolkningsdataflöde (vektorer/sekund) kontra svarstid (ms/fråga) för olika arbetsbelastningsstorlekar.
Post 4 — K-Means-klustring med PDL::Stat::Kmedel
Fil: kmeans.pl
K-medel klustring är ryggraden i inverterad fil index (IVF) tillvägagångssätt för ungefärlig närmaste granne sökning. Detta inlägg täcker:
- Den
PDL::Stat::Kmedelgränssnitt och dess returavtal (centroid,kluster,n,R2,ss). - Att tolka
[obs × kluster]medlemskapsmask returnerad avrun_kmeans. - Jämföra perl/PDL k-medel centroider mot R’s
kmeans()ochClusterR::MiniBatchKmeans()för att validera numerisk korrekthet.
Inlägg 5 — Mini-Batch K-Means: Skalning till stora datamängder
Fil: compare_kmeans_centroids.pl
Full k-means kräver alla data i minnet för varje iteration. Mini-batch k-medel handlar en liten mängd centroid noggrannhet för en stor minskning av minne och beräkning. Den här artikeln utforskar:
- Genomföra en sann återsamplad mini-batch loop i PDL.
- Kvantifiera centroid drift mellan full och mini-batch varianter.
- Utgång sida vid sida med R’s
MiniBatchKmeansfrånClusterRpaket.
Inlägg 6 — Sökning efter index för inverterad fil (IVF)
Fil: compare_ivf_search.pl
Med centroider i handen kan vi partitionera databasen och utföra sublinjär ungefärlig närmaste granne sökning. Detta inlägg täcker:
- Bygga inverterade listor: kartlägga varje databasvektor till närmaste centroid.
- Den
unpack_inverted_listshjälpare iVectorIO. - Querying: söka efter de närmaste centroiderna i topp-K och sedan endast söka efter dessa listor.
- Noggrannhet vs. hastighet avvägningar som antalet probed listor varierar.
Post 7 – Validering mot R: Numerisk korrekthet och korsspråkiga pipeliner
Filer: compare_kmeans_centroids.R, compare_kmeans_centroids_pure.R, plot_centroid_coordinates.R
Det sista inlägget i grundserien stänger slingan mellan Perl och R:
- Exportera PDL-resultat till CSV och läsa dem i R för oberoende validering.
- Använda ggplot2 för att visualisera centroidkoordinater från båda språken samtidigt.
- Ett arbetsflödesmönster för “beräkna i Perl, visualisera i R” som utnyttjar styrkorna i båda ekosystemen.
Nästa upp – Post 1: Serialisering och I/O med
VectorIO.pm
† Moderna processorer har flera nivåer av snabbt minne på chip som kallas cache (L1, L2, L3) som sitter mellan processorkärnorna och huvud-RAM. L1 är den minsta (vanligtvis 32-64 KB per kärna) och snabbaste (1-4 klockcykler latens); L2 är större (256 KB-1 MB) och något långsammare; L3 delas över kärnor (4-64 MB) med högre latens fortfarande. Huvud RAM sitter längre bort vid 60-100 ns latens - ungefär 200× långsammare än L1.
När en beräkning berör minnet i ett förutsägbart, sammanhängande mönster kan maskinvaran prefetcher ladda kommande data till L1/L2 innan det behövs, vilket ger ett nästan högt dataflöde. Spridd pekarsökning (t.ex. genom att korsa en Perl-matris med heap-allokerade skalärer) besegrar förhämtning, stoppar processorn medan den väntar på att varje cache-miss ska lösas från RAM.
