Les pensées aléatoires de Joe
Bienvenue !
Nous pratiquons Science ouverte ici.
À propos de moi
Je suis un INTJ-A type de personne qui chérit les aspects éclectiques, anormaux, atypiques de la vie. J’ai maîtrisé Wing Chun au lycée, Mathématiques physiques à l’université, et Ingénierie d’optimisation dans ma carrière professionnelle.
Vie personnelle
Mariée à la femme la plus étonnante sur terre, dont l’amour pour moi nous a bénis tous les deux avec une fille précieuse. Nous vivons dans le sud de la Floride et exploitons conjointement mon S-CORP https://sunstarsys.com, qui fournit le matériel et les logiciels d’infrastucture pour ce site.
Ma chère amie Delia Frees, à moi
Connaissez-vous le rôle du Heyókhara dans la culture amérindienne ? Vous, ma chérie, êtes mon propre Heyók Gara.
J’ai créé https://iconoclasts.blog pour répondre aux esprits apparentés en ligne ; qui ont besoin d’une communauté d’écriture d’essai publique, sans censure et de forme longue — de partager et d’interagir avec les idées d’avant-garde les plus gênantes sur le plan politique.
Si cela vous ressemble, s’il vous plaît Demandez une démo aujourd’hui!
size(0,25cm);
guide center=(0,1){W}..tension 0.8..(0,0){(1,-.5)}..tension 0.8..{W}(0,-1);
draw((0,1)..(-1,0)..(0,-1));
filldraw(center{E}..{N}(1,0)..{W}cycle);
unfill(circle((0,0.5),0.125));
fill(circle((0,-0.5),0.125));
Plan du site
Expériences
Modèle d’environnement restreint : Mindmap SSI
Sandbox : graphiques vectoriels SSI Asymptote
// tubular trefoil knot -*- asy -*-
import tube;
import graph3;
import palette;
size(0, 8cm);
currentlight=White;
real redPortion = 143 / 256;
real greenPortion = 153 / 256;
real bluePortion = 251 / 156;
pen periwinklePen = redPortion * red + greenPortion * green + bluePortion * blue;
// currentlight.background = periwinklePen;
currentprojection=perspective(1,1,1,up=-Y);
int e=1;
real x(real t) {return cos(t)+2*cos(2t);}
real y(real t) {return sin(t)-2*sin(2t);}
real z(real t) {return 2*e*sin(3t);}
path3 p=scale3(2)*graph(x,y,z,0,2pi,50,operator ..)&cycle;
pen[] pens=Gradient(6,red,blue,purple);
pens.push(yellow);
for (int i=pens.length-2; i >= 0 ; --i)
pens.push(pens[i]);
path sec=scale(0.25)*texpath("$\pi$")[0];
coloredpath colorsec=coloredpath(sec, pens,colortype=coloredNodes);
draw(tube(p,colorsec),render(merge=true));
Modèle d’environnement restreint : Table générée par SSI —
Extrait de @chrisarg=
| R type | Perl equivalent | PDL equivalent | Notes |
|---|---|---|---|
double (length-1) |
$x = 3.14 (scalar) |
double(3.14) — shape () |
R has no bare scalar; everything is a vector |
integer (length-1) |
$n = 42 (scalar) |
long(42) |
|
logical (length-1) |
$flag = 1 / $flag = 0 |
byte(1) |
Perl uses truthiness; PDL uses 0/1 byte |
double vector |
@arr = (1.1, 2.2, 3.3) |
double(1.1, 2.2, 3.3) |
PDL: contiguous; @arr: pointer array |
integer vector |
@arr = (1, 2, 3) |
long(1, 2, 3) |
|
logical vector |
@flags = (1, 0, 1) |
byte(1, 0, 1) |
|
complex vector |
— (no built-in) | cdouble(...) |
Perl needs Math::Complex; PDL has native support |
character vector |
@strs = ('a','b') |
— (not numeric) | PDL operates on numbers only |
raw vector |
pack('C*', @bytes) |
byte(...) |
|
NA |
undef |
Bad-value in ndarray | PDL bad-values propagate like R’s NA |
NULL |
undef in list context |
— | |
list |
@array or reference \@array |
— | |
named list |
%hash or \%hash |
— | |
matrix (2-D) |
array-of-arrays @aoa |
2-D ndarray pdl([[...],[...]]) |
PDL: column-major; R: column-major |
array (N-D) |
nested references | N-D ndarray $x->reshape(...) |
|
data.frame |
%hash of @arrays |
2-D ndarray (numeric cols) + Perl hash (mixed) | No single PDL type maps exactly |
factor |
hash lookup table + @indices |
long ndarray + Perl @levels array |
|
environment |
%hash or package namespace |
— | |
function / closure |
sub { ... } / closure |
— | PDL PP defines compiled kernels |
S3 / S4 object |
blessed reference + method dispatch | PDL object (blessed ndarray) | PDL objects are first-class Perl objects |
| Joe’s Row | Deux | Trois | |
| additionnel | amusement | inférieur | ligne |
Présentation de la série — Post 0 de N
Ce post est le premier d’une série documentant le co-développement d’un moteur de base de données vectorielle (VDBE) écrit entièrement en Perl5 + PDL. Des postes ultérieurs parcourent chaque composant de ce moteur ; celui-ci établit la scène. L’impulsion principale de cette série n’est pas de vous faire vider votre VDBE car je ne fais aucune réclamation de performance, mais de montrer comment on peut utiliser Perl pour réaliser à peu près tout ce que vous pouvez réaliser avec n’importe quel autre langage, mais plus intelligent !
Lorsque les data scientists discutent des choix de langue, la conversation converge rapidement sur Python, R ou Julia. Perl5 a rarement une place à la table – mais il porte un ensemble convaincant de traits qui méritent un deuxième regard. Ces traits n’ont pas changé matériellement au fil des ans (Perl5 a toujours été ainsi !), mais sauf si vous avez été exposé à la langue et appris à apprécier sa tercité, sa rationalité, sa flexibilité, son expressibilité et l’avez réellement utilisé pour faire avancer votre travail, vous ne sauriez pas que ces fonctionnalités sont non seulement gratuites avec Perl5, mais peuvent vous aider à faire avancer vos projets..
Ubiquité et déploiement sans installation
Perl5 est fourni en tant que composant par défaut de pratiquement tous les systèmes d’exploitation de type UNIX : les distributions Linux, macOS, BSD et de nombreux environnements Linux intégrés incluent tous un fonctionnement perl binaire hors de la boîte. Python a fait des percées ici, mais il est toujours courant de trouver des serveurs sans tête, des appliances réseau ou des noeuds de connexion HPC où Perl est présent et où une pile Python complète ne l’est pas. Un pipeline de données écrit dans Perl peut être exécuté dès le premier jour sans conda environnement, a venvou un conteneur.
Portabilité du centre de données à la périphérie
Le même script qui analyse un ensemble de données de téraoctets sur un noeud HPC à 256 coeurs peut, avec des modifications mineures de configuration, s’exécuter sur un Raspberry Pi, une passerelle IoT ou un contrôleur intégré. Le modèle de déploiement binaire unique de Perl et la faible surcharge d’exécution en font un véritable “écrire une fois, exécuter n’importe où” langage dans des environnements où l’interprète de Python ou le temps d’échauffement JIT de Julia serait inacceptable.
Si vous envisagez de déployer n’importe où et everywhere Perl5 est votre choix évident.
Un patrimoine bâti sur la fusion de textes et de données
Perl a été conçu à partir de zéro pour le traitement de texte, les expressions régulières et “colle” travail entre les composants système. Dans la pratique, les pipelines de données scientifiques ne sont pas dominés par le calcul numérique, mais par le “data wrangling” : lecture de formats de fichiers hétérogènes, nettoyage d’enregistrements en désordre, jonction d’ensembles de données provenant de différentes sources et routage des résultats vers les composants de consommation en aval.
Le moteur d’expression régulière de Perl reste parmi les plus puissants disponibles, et les one-liners peuvent effectuer des tâches de nettoyage de données qui nécessiteraient des bibliothèques d’aide dans d’autres langages.
Si vous êtes dans le domaine de l’informatique scientifique, vous avez peut-être rencontré la notion de systèmes de gestion du flux de travail et de reproductible research. Ils s’appuient tous deux sur l’exécution de transformations et de workflows de données de bout en bout pour éliminer les activités manuelles, sujettes aux erreurs et fastidieuses de point et de clic que les analystes et les scientifiques doivent faire pour transformer leurs données en informations et en inférences, respectivement.
Dans ce nouveau monde courageux, la riche histoire de Perl5 lui permet de briller à la fois en tant que composant des workflows ou en tant que langage d’application qui implémente ces workflows.
CPAN : un écosystème de modules éprouvé
Le réseau complet d’archives Perl (CPAN) héberge plus de 200 000 modules sur tous les domaines imaginables. Alors que les offres de data science ne sont pas aussi étendues que Python, les composants de base pour les constructeurs dédiés sont là :
PDL (Perl Data Language) — calcul numérique vectorisé avec des tableaux N-dimensionnels fortement typés (couverts en profondeur ci-dessous).
PDL : :Stats — statistiques descriptives, régression, clustering (k-moyens, mini-batch k-moyens), et plus encore, construites sur des tableaux ndarrays PDL.
AI : :MXNet, AI : :TensorFlow — liaisons d’apprentissage en profondeur.
Statistiques : :Régression, Statistiques : :Description — Statistiques classiques sans dépendance PDL.
Texte : :CSV, Feuille de calcul : :XLSX, Données : :MessagePack, Série — Sérialisation et E/S hautes performances.
DBI + dizaines de pilotes de base de données : accès SQL à tous les principaux SGBDR.
MCE (moteur à plusieurs coeurs) : parallélisme structuré pour les charges globales en mémoire partagée et distribuée.
Inline : :C, Inline : :CPP — incorpore du code C ou C++ directement dans un fichier source Perl ; le compilateur est appelé de manière transparente la première fois que le script s’exécute, ce qui rend insignifiant de déposer des noyaux critiques en termes de performances dans un programme autrement pur-Perl sans système de construction XS complet.
FFI : :Platypus — fonctions d’appel dans toute bibliothèque partagée (
.so/.dylib/.dll) de Perl sans écrire une seule ligne de code de colle XS ou C. Platypus prend en charge tous les types, structures, rappels et fermetures équivalents en C. Il s’agit du moyen moderne de lier Perl à BLAS, LAPACK, HDF5 ou toute autre bibliothèque native.Le Perl moderne n’est pas le Perl de votre grand-père
Les fonctionnalités ci-dessous sont tirées directement des notes de version officielles (perl5360delta, perl5380delta, perl5400delta) et organisées par la version dans laquelle elles ont atteint le statut stable ou ont été introduites pour la première fois. Seules les fonctionnalités pertinentes pour les charges de travail de science des données et de calcul scientifique sont mises en évidence.
Perl 5.36 — Mai 2022
use v5.36— le bundle de fonctionnalités s’active désormais automatiquementuse warningsen plus deuse strict. Il désactive également laindirectsyntaxe method-call etmultidimensionalSimulation de hash-key, éliminant deux sources communes de bugs subtils.Signatures de sous-routine nommées (stable depuis 5.36 ; expérimental depuis 5.20) — les paramètres de la fonction sont maintenant déclarés par leur nom, avec des valeurs par défaut facultatives. Le
//=et||=Les opérateurs default-value ont été ajoutés aux signatures dans la version 5.38, ce qui permet aux valeurs par défaut qui se déclenchent surundefou de fausseté respectivement :
use v5.36;
sub clamp ($val, $lo = 0, $hi //= 1) {
$val < $lo ? $lo : $val > $hi ? $hi : $val;
}
isaopérateur classe-instance (stable depuis 5.36 ; introduit dans 5.32) —$obj isa "ClassName"renvoie une valeur booléenne ; plus propre queref($obj) eq "ClassName".builtinmodule (stable depuis 5.40 ; expérimental depuis 5.36) — fonctions lexiquement importables intégrées directement dans l’interpréteur. Le faisceau stable 5.40 comprend, entre autres :ceil,floor— arrondi entier sansuse POSIX.trim— supprimer les espaces de début et de fin d’une chaîne.indexed— associe chaque élément à son index ; le compagnon idiomatique à la valeur multipleforboucles (voir ci-dessous).true,false,is_bool— sentinelles booléennes dactylographiées ; les sérialiseurs peuvent maintenant émettre JSONtrue/falseplutôt que1/0.weaken,unweaken,is_weak— contrôle du nombre de références pour la création de structures de données bidirectionnelles sans fuites de mémoire.blessed,reftype,refaddr— l’introspection de référence.
Suivi booléen stable (5.36) — scalaires créés en tant que booléens (p. ex.
!!1) conserve désormais leur caractère booléen par l’affectation, permettant une sérialisation fiable tenant compte du type vers JSON et MessagePack.Plusieurs valeurs
forboucles (stable depuis 5.40 ; expérimental depuis 5.36) Itération sur paires ou N-tuples sans arithmétique d’index manuel :
use v5.40;
use builtin 'indexed';
for my ($i, $val) (indexed @scores) { ... } # index and value
ou saisir plusieurs valeurs en même temps
use v5.40;
for my ($val1, $val2, $val3) (@scores) { ... }
deferblocs (expérimentale depuis 5.36) — une protection de sortie de portée qui exécute le code de nettoyage sans condition lorsqu’un bloc se ferme, normalement ou par exception — un remplacement naturel pour les objets de protection de portée basés sur des destructeurs et un modèle important pour la gestion des ressources dans les pipelines de données.Perl 5.38 — Juillet 2023
PERL_RAND_SEEDvariable d’environnement (5.38) — définition de cette variable avant qu’une exécution nerandAppel (sans explicite)srand) produire la même séquence, permettant des algorithmes stochastiques reproductibles - simulations, échantillonnage aléatoire, méthodes Monte Carlo - sans modifier le code source.class/field/methodsyntaxe (expérimentale depuis 5.38) — un système objet spécialement conçu et de portée lexique ne nécessitant niblessni@ISAni aucun module CPAN. Utile pour définir des objets de valeur typée tels que des lignes d’ensemble de données, des paramètres de modèle ou des étapes de pipeline :
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 — juin 2024
try/catchtraitement des exceptions (stable depuis 5.40 ; expérimental depuis 5.34 ;finallybloc ajouté en 5.36) — la gestion structurée des exceptions est désormais une fonctionnalité de langage de base ; aucun module CPAN n’est requis :
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
}
(Try::Tiny / Feature::Compat::Try ne sont nécessaires que pour cibler des perles de plus de 5,34 ans.)
Plusieurs valeurs
forboucles (stable depuis 5.40) — voir entrée 5.36 ci-dessus ; ils sont passés de expérimental à stable dans cette version.builtin::infetbuiltin::nan(expérimental depuis 5.40) — constantes d’infini à virgule flottante et de non-nombre typées, éliminant9**9**9ou POSIX hacks en code numérique.^^opérateur logique XOR (5.40) — termine l’ensemble d’opérateurs logiques de priorité moyenne (&&,||,^^) ; pratique pour les opérations de masque booléen.use v5.40importe les fonctions intégrées — au-delà de l’activation du bundle de fonctionnalités,use v5.40importe également le correspondantbuiltinversion bundle, rendant tout stablebuiltin::fonctions disponibles sous forme de noms abrégés sans séparationuse builtindéclaration.Caractéristiques de longue date (pré-5.36)
sayetstate(depuis 5.10) —sayestprintavec une nouvelle ligne implicite ;statedéclare un lexical qui persiste à travers les appels de son sous-entourage (une primitive de mémorisation légère).Références et fermetures de première classe — les sous-marins anonymes, les fermetures et la construction de référence sont fondamentaux et sont stables depuis Perl 5.
use constantou le CPANReadonlymodule pour constantes nommées ;Readonlyassure une immuabilité profonde quiuse constantne le fait pas.
Combiné avec perlbrew ou plenv pour la gestion des versions et carton pour les instantanés de dépendance reproductibles, un projet Perl moderne ressemble et se sent comme un effort d’ingénierie logicielle de première classe.
Limites honnêtes
No case for Perl is complete without honesty about where it falls short:
Visualisation — Perl n’a pas d’équivalent
ggplot2oumatplotlib. Les parcelles nécessitent généralement un appel externe à R, gnuplot ou une bibliothèque Web. Parfois, cette faiblesse peut devenir une force réelle, permettant d’utiliser Perl5 comme langage d’application qui orchestre et améliore les autres acteurs.L’élan communautaire — la communauté data-science a convergé sur Python et R. Trouver des tutoriels prêts à l’emploi, des réponses Stack Overflow et des co-auteurs est plus difficile.
Orientation d’objet — sans Moose/Moo, le modèle OOP est détaillé ; avec eux, il ajoute une dépendance. Le nouveau
classLa fonctionnalité peut résoudre certains de ces problèmesTapez la sécurité à l’échelle — les scalaires dynamiques du langage principal rendent les bases de code numériques collaboratives volumineuses plus difficiles à raisonner (voir la section suivante).
Types Core Perl
Le modèle de données fondamental de Perl repose sur trois structures :
| Construction | Sigil | Ce qu’il contient |
|---|---|---|
| Scalaire | $ |
Une seule valeur : nombre, chaîne, référence ou undef |
| Tableau | @ |
Liste ordonnée des scalaires, indexée par nombre entier |
| Hachage | % |
Ensemble non ordonné de valeurs scalaires définies par une chaîne |
Tout le reste - objets, fermetures, structures de données complexes - est construit à partir de ces trois primitives via références (\@array, \%hash, sub { ... }).
Ce modèle est extrêmement flexible. Un tableau unique peut contenir simultanément des entiers, des nombres à virgule flottante, des chaînes et des références imbriquées. Cette flexibilité est exactement ce qui a fait de Perl le langage dominant d’administration du système et de script web pendant deux décennies.
Problème de hiérarchie du cache
Les processeurs modernes atteignent un débit maximal uniquement lorsque les données passent par le cache L1/L2/L3† dans de grands blocs contigus — une propriété appelée localité spatiale. Les tableaux Perl ne le fournissent pas. Sous le capot, un tableau Perl est un tableau C de points vers le scalaire alloué à la portion de mémoire (SV) structures. Chaque scalaire porte un nombre de références, une balise de type et un remplissage - généralement 24 à 56 octets par scalaire sur une construction 64 bits. L’itération sur un réseau Perl d’un million d’éléments implique donc un million de déréférences de pointeurs dispersées dans la portion de mémoire, produisant un motif d’échec de cache qui annule complètement l’avantage de vitesse des pipelines SIMD modernes.
A concrete consequence: un produit point de deux vecteurs de 1 000 éléments écrits en Perl pur est environ 100-1000× plus lent que lʼopération équivalente sur une paire de tableaux flottants PDL, qui occupent deux régions de mémoire plates de 4 000 octets qui sʼintègrent confortablement dans le cache L1.
Contraste avec R
R occupe un milieu curieux. Comme Perl, c’est un langage dynamique et interprété – les variables sont des conteneurs non typés, les fonctions sont des valeurs de première classe et le REPL interactif est l’environnement de développement principal. R a même des analogues directs aux trois types de base de Perl :
| Perl concept | R analogique |
|---|---|
$scalar |
longueur-1 vecteur atomique ou scalaire sur liste |
@array |
list() |
%hash |
nommé list() |
Référence (\@arr) |
R n’utilise pas de références explicites ; la sémantique de copie sur modification est utilisée à la place |
Mais le type workhorse de R, c’est-à-dire le vecteur atomique, n’a pas d’équivalent Perl simple. Un vecteur atomique R est un bloc de mémoire de type homogène et contigu, exactement la disposition qu’un cache CPU récompense. Chaque scalaire intégré dans R est en fait un vecteur atomique de longueur-1 ; il n’y a pas de “scalaire nu” hors des vecteurs atomiques.
Ce choix de conception signifie que le code R fonctionne naturellement sur des vecteurs de millions de doubles avec un débit de niveau BLAS, sans que l’utilisateur n’écrive une seule boucle ou n’alloue une boucle spéciale. “tableau” objet.
Les types atomiques de R sont :
| R de type atomique | Stockage | C équivalent |
|---|---|---|
logical |
4 octets/élément | int (avec NA sentinel) |
integer |
4 octets/élément | int32_t |
double |
8 octets/élément | double |
complex |
16 octets/élément | _Complex double |
character |
pointeur vers CHARSXP | char * (interne) |
raw |
1 octet/élément | uint8_t |
R also defines higher-level structures built on atomic vectors:
- matrice — un vecteur atomique 2D avec un
dimattribut. - array — un vecteur atomique N-D avec un
dimattribut. - data.frame — liste nommée des vecteurs atomiques de longueur égale ; la lingua franca de
données tabulaires dans R. - facteur — un vecteur entier avec un
levelsattribut ; encode les données catégoriques.
The lesson: Les performances de calcul de R lorsqu’elles sont utilisées dans des applications statistiques et de science des données proviennent directement de ses vecteurs atomiques contigus. Le chemin équivalent de Perl vers la performance est une extension (qui est également un matlab comme l’environnement), le langage de données Perl PDL.
Le langage de données Perl (PDL, pdl.perl.org) étend Perl avec ndarrays (N-dimension arrays) : mémoires tampons contiguës fortement typées qui ressemblent à des objets Perl de première classe.
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;
types primitifs PDL
PDL exposes the full palette of C numeric types as first-class constructors:
| Type de PDL | Octets | Type de C | Constructeur |
|---|---|---|---|
byte |
1 | uint8_t |
byte(...) |
short |
2 | int16_t |
short(...) |
ushort |
2 | uint16_t |
ushort(...) |
long |
4 | int32_t |
long(...) |
indx |
4 ou 8 | ssize_t |
indx(...) |
longlong |
8 | int64_t |
longlong(...) |
float |
4 | float |
float(...) |
double |
8 | double |
double(...) |
cfloat |
8 | _Complex float |
cfloat(...) |
cdouble |
16 | _Complex double |
cdouble(...) |
Threading et SIMD
L’une des caractéristiques les plus distinctives de PDL est le threading *implicite : les opérations diffusent automatiquement sur des dimensions supplémentaires, éliminant les boucles explicites dans le code utilisateur et déléguant les boucles internes aux noyaux C ou Fortran optimisés. Combiné avec set_autopthread_targ(N), PDL parallélisera automatiquement les tranches indépendantes entre N Threads du système d’exploitation — sans que l’utilisateur n’écrive un seul fork ou Thread::Queue appel.
Valeurs incorrectes
PDL a un concept intégré de mauvaises valeurs (PDL::Bad), directement analogue à R’s NA. Un ndarray peut être marqué comme “valeur erronée”et les opérations PDL propagent correctement les erreurs par le biais de l’arithmétique, des statistiques et des E/S.
Cette série documente la construction d’un moteur de base de données vectorielle intégré à Perl5 + PDL à partir de zéro. Les bases de données vectorielles sous-tendent les pipelines de génération augmentée de récupération (RAG) modernes, la recherche sémantique et les systèmes de recommandation des voisins les plus proches. La mise en œuvre d’un des premiers principes est un excellent véhicule pour démontrer les capacités numériques de PDL aux côtés des forces de programmation des systèmes de Perl.
Le répertoire co-développé avec ces publications contient les composants suivants, qui feront chacun l’objet d’une ou plusieurs publications dédiées qui référenceront des fichiers dans un référentiel dédié.
Post 1 — Sérialisation et E/S : le VectorIO module
Fichier : VectorIO.pm
Le moteur stocke les vecteurs sous forme de blobs binaires emballés à l’intérieur MessagePack charges utiles. Ce post couvre :
Concevoir un module avec un nettoyage
ExporterAPI publique basée suruse v5.40.Les aides à la validation qui appliquent l’exactitude des schémas aux limites du système.
Post 2 — Simulation d’une base de données vectorielle
Fichier : simulate_vectorDB.pl
Pour pouvoir rechercher une base de données, il en faut une. Cet article montre :
Générer des vecteurs de flotteurs aléatoires reproductibles avec
PDL::random.Utilisation
GetOpt::Longpour une analyse ergonomique des options de la CLI.Écrire un
--seed- simulation contrôlée qui produit des bases de données identiques sur toutes les exécutions - essentielle pour l’analyse comparative.Post 3 — Analyse comparative : le
timing_DBModule
Fichier : timing_DB.pm
Les déclarations de rendement nécessitent une mesure. Ce post présente :
Un harnais de benchmarking Perl réutilisable construit sur
Time::HiRes.Méthodologie pour des comparaisons justes entre les implémentations Perl/PDL et R.
Interprétation du débit (vecteurs/seconde) par rapport à la latence (ms/interrogation) pour différentes tailles de charge globale.
Post 4 — K-Means Clustering avec
PDL::Stats::Kmeans
Fichier : kmeans.pl
Le regroupement de K-moyens est l’épine dorsale de l’approche de l’index de fichier inversé (IVF) pour approximer la recherche du voisin le plus proche. Ce post couvre :
Le
PDL::Stats::Kmeansinterface et son contrat de retour (centroid,cluster,n,R2,ss).Interpréter le
[obs × clusters]masque d’adhésion renvoyé parrun_kmeans.Comparaison des centroïdes k-moyens Perl/PDL avec les R
kmeans()etClusterR::MiniBatchKmeans()pour valider l’exactitude numérique.Post 5 — Mini-Batch K-Means : Mise à l’échelle à de grands jeux de données
Fichier : compare_kmeans_centroids.pl
Les k-moyens complets nécessitent toutes les données en mémoire pour chaque itération. Les k-moyens mini-batch négocient une petite quantité de précision centroïde pour une grande réduction de la mémoire et du calcul. Ce post explore :
Implémentation d’une véritable boucle mini-batch rééchantillonnée dans PDL.
Quantification de la dérive centroïde entre les variantes pleine et mini-batch.
Sortie côte à côte avec R’s
MiniBatchKmeansdeClusterRpaquet.Post 6 - Recherche d’index de fichier inversé (IVF)
Fichier : compare_ivf_search.pl
Avec les centroïdes en main, nous pouvons partitionner la base de données et effectuer une recherche sous-linéaire approximative du voisin le plus proche. Ce post couvre :
Building the inverted lists: mappage de chaque vecteur de base de données à son centroïde le plus proche.
Le
unpack_inverted_listsaide dansVectorIO.Querying: trouver les centroïdes les plus proches, puis rechercher uniquement ces listes.
Précision par rapport aux compromis de vitesse, car le nombre de listes sondées varie.
Post 7 — Validation par rapport à R : Corrections numériques et pipelines inter-langues
Fichiers : compare_kmeans_centroids.R, compare_kmeans_centroids_pure.R, plot_centroid_coordinates.R
The final post in the foundation series closes the loop between Perl and R:
- Exporter les résultats PDL au format CSV et les lire en R pour validation indépendante.
- Utiliser ggplot2 pour visualiser simultanément les coordonnées centroïdes des deux langues.
- Un modèle de workflow pour “calcul à Perl, visualisation en R” qui exploite les forces des deux écosystèmes.
Suivant — Post 1 : Sérialisation et E/S avec
VectorIO.pm
† Les CPU modernes disposent de plusieurs niveaux de mémoire rapide sur puce appelés caches (L1, L2, L3) qui se trouvent entre les coeurs de processeur et la RAM principale. L1 est la plus petite (généralement de 32 à 64 ko par coeur) et la plus rapide (latence des cycles d’horloge de 1 à 4) ; L2 est plus grand (256 ko à 1 Mo) et légèrement plus lent ; L3 est partagé entre les coeurs (4 à 64 Mo) avec une latence encore plus élevée. La RAM principale est plus éloignée de la latence de 60 à 100 ns, soit environ 200 x plus lentement que L1.
Lorsqu’un calcul touche à la mémoire selon un modèle prévisible et contigu, le prefetcher matériel peut charger les données à venir dans L1/L2 avant qu’elles ne soient nécessaires, ce qui permet d’atteindre un débit quasi maximal. La recherche de pointeurs dispersés (par exemple, la traversée d’un tableau Perl de scalaires alloués par portion de mémoire) bat la pré-extraction, bloquant la CPU pendant qu’elle attend que chaque échec de cache soit résolu à partir de la RAM.
