Visitados recentemente
Visitados recentemente

Pensamentos Aleatórios de Joe

[VERIFICADO] Última atualização por Joe Schaefer em dom, 14 jun 2026    origem
 

Heyoka

Bem-vindo!

Nós praticamos Ciência aberta aqui.

Sobre mim

Sou um AJUSTE-A tipo de pessoa que aprecia os aspectos ecléticos, anormais e atípicos da vida. Eu dominei Wing Chun no ensino médio, Matemática Física na Universidade, e Engenharia de Otimização na minha carreira profissional.

Vida pessoal

Casado com a mulher mais incrível da Terra, cujo amor por mim nos abençoou com uma filha preciosa. Vivemos no sul da Flórida e operamos conjuntamente meu S-CORP https://sunstarsys.com, que fornece o hardware e o software de infraestrutura para este site.

Minha querida amiga Delia Frees, para mim

Você está familiarizado com o papel que o Heyók 2a desempenha na cultura nativa americana? Você, minha querida, é minha própria Heyók.

Grok Heyoka

Eu criei https://iconoclasts.blog para atender a espíritos afins on-line; que precisam de uma comunidade de redação de redação pública, livre de censura e de forma longa — compartilhar e interagir com as ideias mais politicamente inconvenientes e de vanguarda.

Se isso soa como você, por favor solicite uma demonstração hoje mesmo!

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));

Plano

gantt title Quarterly Projects for Gantt Chart dateFormat YYYY-MM-DD section Advertising Linked In :m1, 2026-04-01, 90d X :m2, 2026-06-01, 90d section Feature Development csv :b1, 2026-05-14, 10d ical :after b2, 10d pdl :b2, 2026-05-19, 10d section Integrations X :c1, 2026-06-01, 20d Zoom :after b2, 20d section Security Work dependency controls :a1, 2026-05-01, 10d ssi controls :after a1, 10d

pie title 2026 Q2 Budget Priorities "Marketing e Publicidade" : 60 "Desenvolvimento" : 20 "Operações" : 20

Experimentos

Sandbox: Mindmap do SSI

mindmap root((KMS)) (Plataformas Wiki) ((Orion)) [Confluência] [Noção] (Controle de Versão) [Usos] Curadoria de Conteúdo Controles de Acesso Histórico imutável [Ferramentas] Git Subversão (Jamstack) [CMS] Autores Pesquisadores Curadores [Compilações de sites] Desenvolvedores Arquitetos [Segurança] (IA) RAG CLIENTE

Sandbox: Gráficos vetoriais assintóticos do SSI

// 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));

Sandbox: Tabela gerada pelo SSI — camel-emoji-dave_camel Extraído 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 Dois Três
adicional diversão abaixo linha

 

Ciência de Dados

Introdução da série — Post 0 de N
Este post é o primeiro de uma série documentando o co-desenvolvimento de um mecanismo de banco de dados vetorial (VDBE) escrito inteiramente em Perl5 + PDL. Postagens posteriores passam por todos os componentes desse motor; este define o palco. O principal impulso para esta série não é ter você despejar seu VDBE como eu não fazer reivindicações de desempenho, mas para mostrar como se pode usar Perl para conseguir praticamente qualquer coisa que você pode conseguir com qualquer outro idioma, mas mais inteligente!


  1. Por que Perl5 para o Data Science?

Quando os cientistas de dados discutem as escolhas de linguagem, a conversa converge rapidamente em Python, R ou Julia. Perl5 raramente tem um assento na mesa - ainda que ele carrega um conjunto atraente de características que merecem uma segunda olhada. Esses traços não mudaram materialmente ao longo dos anos (Perl5 sempre foi assim!), mas a menos que você tenha sido exposto ao idioma e aprendido a apreciar sua tercidade, racionalidade, flexibilidade, expressibilidade e realmente o tenha usado para impulsionar seu trabalho, você não saberia que esses recursos não só vêm de graça com o Perl5, mas podem ajudá-lo a impulsionar seus projetos.

Implantação de ubiquidade e instalação zero

O Perl5 é fornecido como um componente padrão de praticamente todos os sistemas operacionais semelhantes ao UNIX — distribuições Linux, macOS, BSDs e muitos ambientes Linux incorporados incluem um trabalho perl binário fora da caixa. Python tem feito incursões aqui, mas ainda é comum encontrar servidores headless, appliances de rede ou nós de login HPC onde Perl está presente e uma pilha Python completa não está. Um pipeline de dados gravado em Perl pode ser executado no primeiro dia sem um conda ambiente, a venvou um recipiente.

Portabilidade do data center para a borda

O mesmo script que analisa um conjunto de dados de terabyte em um nó HPC de 256 núcleos pode, com pequenas alterações de configuração, ser executado em um Raspberry Pi, um gateway IoT ou um controlador incorporado. O modelo de implantação monobinário da Perl e a baixa sobrecarga de runtime o tornam genuíno “escreva uma vez, corra em qualquer lugar” em ambientes onde a sobrecarga do intérprete de Python ou o tempo de aquecimento JIT de Julia seriam inaceitáveis.

Se você está planejando implantar em qualquer lugar e everywhere Perl5 é sua escolha óbvia.

Uma herança construída com base na extração de texto e dados

Perl foi projetado do zero para processamento de texto, expressões regulares e “cola” trabalho entre os componentes do sistema. Na prática, os pipelines de dados científicos são dominados não por computação numérica, mas por data wrangling: leitura de formatos de arquivo heterogêneos, limpeza de registros confusos, junção de conjuntos de dados de diferentes fontes e roteamento de resultados para componentes de consumo downstream.

O mecanismo regex da Perl permanece entre os mais poderosos disponíveis, e uma linha pode realizar tarefas de limpeza de dados que exigiriam bibliotecas auxiliares em outros idiomas.

Se você está no domínio da computação científica, você pode ter se deparado com a noção de sistemas de gerenciamento de fluxo de trabalho e pesquisa reproduzível. Ambos dependem da execução de transformações de dados de ponta a ponta e do fluxo de trabalho para eliminar as atividades manuais, propensas a erros e tediosas de apontar e clicar que analistas e cientistas precisam fazer para transformar seus dados em insights e inferências, respectivamente.

Neste admirável mundo novo, a rica história do Perl5 permite que ele brilhe tanto como um componente de fluxos de trabalho quanto como uma linguagem de aplicativo que implementa esses fluxos de trabalho.

CPAN: um ecossistema de módulos testados em batalha

A Rede Abrangente de Arquivos Perl (CPAN) hospeda mais de 200.000 módulos em todos os domínios imagináveis. Embora as ofertas de ciência de dados não sejam tão extensas quanto o Python, os componentes básicos para construtores dedicados ESTÃO lá:

  • PDL (Perl Data Language) — computação numérica vetorizada com arrays N-dimensionais fortemente digitados (abrangidos em profundidade abaixo).

  • PDL::Stats — estatística descritiva, regressão, clustering (k-means, mini-batch k-means) e muito mais, construído em cima de matrizes de PDL.

  • AI::MXNet, AI::TensorFlow — associações de aprendizado profundo.

  • Estatísticas::Regressão, Estatísticas::Descritivas — estatísticas clássicas sem a dependência de PDL.

  • Text::CSV, Spreadsheet::XLSX, Data::MessagePack, Sereal — serialização de alto desempenho e E/S.

  • DBI + dezenas de drivers de banco de dados — acesso SQL a todos os principais RDBMS.

  • MCE (Mecanismo de muitos núcleos) — paralelismo estruturado para cargas de trabalho de memória compartilhada e distribuída.

  • Inline::C, Inline::CPP — incorpora código C ou C++ diretamente dentro de um arquivo de origem Perl; o compilador é chamado de forma transparente na primeira vez que o script é executado, tornando trivial soltar kernels críticos de desempenho em um programa de outra forma puro-Perl sem um sistema de compilação XS completo.

  • FFI::Platypus — funções de chamada em qualquer biblioteca compartilhada (.so / .dylib / .dll) de Perl sem escrever uma única linha de código de cola XS ou C. O Platypus suporta todos os tipos, estruturas, callbacks e fechamentos equivalentes em C, e é a maneira moderna de vincular Perl a BLAS, LAPACK, HDF5 ou qualquer outra biblioteca nativa.

    Perl 5.36 — Maio de 2022

  • use v5.36 — o pacote de recursos agora ativa automaticamente use warnings Além de use strict. Também desabilita o indirect sintaxe de chamada de método e multidimensional simulação de hash-key, eliminando duas fontes comuns de bugs sutis.

  • Assinaturas de sub-rotina nomeadas (estável desde 5.36; experimental desde 5.20) — parâmetros de função agora são declarados por nome, com padrões opcionais. O //= e ||= operadores de valor padrão foram adicionados às assinaturas na versão 5.38, permitindo padrões que acionam undef ou falsidade, respectivamente:

  use v5.36;
  sub clamp ($val, $lo = 0, $hi //= 1) {
      $val < $lo ? $lo : $val > $hi ? $hi : $val;
  }
  • isa operador de classe (estável desde 5.36; introduzido no ponto 5.32)$obj isa "ClassName" retorna um valor booliano; mais limpo que ref($obj) eq "ClassName".

  • builtin módulo (estável desde 5.40; experimental desde 5.36) — funções lexicamente importáveis incorporadas diretamente no intérprete. O pacote estável 5.40 inclui, entre outros:

  • ceil, floor — arredondamento inteiro sem use POSIX.

    • trim — tira o espaço em branco à esquerda/à direita de uma string.
    • indexed — emparelha cada elemento com seu índice; o companheiro idiomático ao multi-valor for loops (veja abaixo).
    • true, false, is_bool - sentinelas booleanas digitadas; serialisers agora podem emitir JSON true/false em vez de 1/0.
    • weaken, unweaken, is_weak — controle de contagem de referência para a construção de estruturas de dados bidirecionais sem vazamentos de memória.
    • blessed, reftype, refaddr — introspecção de referência.
  • Rastreamento booliano estável (5.36) — escalares criados como boolianos (por exemplo, !!1) agora mantêm sua natureza booleana por meio da atribuição, permitindo a serialização confiável com reconhecimento de tipo para JSON e MessagePack.

  • Vários valores for loops (estável desde 5.40; experimental desde 5.36) Iterar sobre pares ou N-tuplos sem aritmética de índice manual:

  use v5.40;
  use builtin 'indexed';

for my ($i, $val) (indexed @scores)  { ... } # index and value

Ou pegar vários valores ao mesmo tempo

  use v5.40;

for my ($val1, $val2, $val3) (@scores)  { ... }
  • defer blocos (experimental desde 5.36) — um protetor de saída de escopo que executa o código de limpeza incondicionalmente quando um bloco sai, normalmente ou por exceção — um substituto natural para objetos de proteção de escopo baseados em destruidores e um padrão importante para o gerenciamento de recursos em pipelines de dados.

    Perl 5.38 — Julho de 2023

  • PERL_RAND_SEED variável de ambiente (5.38) — definir essa variável antes que uma execução faça cada rand chamada (sem explícita) srand) produzem a mesma sequência, permitindo algoritmos estocásticos reproduzíveis — simulações, amostragem aleatória, métodos de Monte Carlo — sem modificar o código-fonte.

  • class / field / method sintaxe (experimental desde 5.38) — um sistema de objetos com escopo lexical específico que não requer nenhuma bless nem @ISA nem qualquer módulo CPAN. Útil para definir objetos de valor digitado, como linhas de conjunto de dados, parâmetros de modelo ou estágios 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 — Junho de 2024

  • try / catch Tratamento de exceções (estável desde 5.40; experimental desde 5.34; finally bloco adicionado em 5.36) — o tratamento estruturado de exceções é agora um recurso de linguagem principal; nenhum módulo CPAN é necessário:
  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 são necessários apenas quando a segmentação perls for superior a 5,34.)

  • Vários valores for loops (estável desde 5.40) — ver 5.36 entrada acima; eles se graduaram de experimental para estável nesta versão.

  • builtin::inf e builtin::nan (experimental desde 5.40) — infinito de ponto flutuante digitado e constantes Não-um-Número, eliminando 9**9**9 ou POSIX hackeia em código numérico.

  • ^^ operador lógico XOR (5.40) — completa o conjunto de operadores lógicos de média precedência (&&, ||, ^^); útil para operações de máscara booliana.

  • use v5.40 importa funções incorporadas — além de habilitar o pacote de recursos, use v5.40 também importa o correspondente builtin pacote de versão, tornando tudo estável builtin:: funções disponíveis como nomes curtos sem use builtin instrução.

    Características de longa data (pré-5.36)

  • say e state(desde 5.10)* — say é print com uma nova linha implícita; state declara um lexical que persiste através de invocações de seu sub delimitador (um primitivo de memorização leve).

  • Referências e fechamentos de primeira classe — subs anônimos, fechamentos e construção de referência são fundamentais e têm sido estáveis desde a Perl 5.

  • use constant ou o CPAN Readonly módulo para constantes nomeadas; Readonly impõe imutabilidade profunda que use constant não.

Combinado com perlbrew ou plenv para gerenciamento de versões e carton para snapshots de dependência reproduzíveis, um projeto Perl moderno parece e se sente como um esforço de engenharia de software de primeira classe.

Limitações honestas

No case for Perl is complete without honesty about where it falls short:

  • Visualização — Perl não tem equivalente a ggplot2 ou matplotlib. Plots normalmente requerem uma chamada externa para R, gnuplot, ou uma biblioteca web. Às vezes, esse ponto fraco pode se tornar um ponto forte real, permitindo que se use Perl5 como a linguagem do aplicativo que orquestra e aprimora os outros atores.

  • Momento comunitário — a comunidade de ciência de dados convergiu em Python e R. Encontrar tutoriais prontos, respostas do Stack Overflow e coautores é mais difícil.

  • Orientação do objeto — sem Moose/Moo o modelo OOP é detalhado; com eles adiciona uma dependência. O novo class recurso pode resolver alguns desses problemas

  • Digite segurança em escala — os escalares dinâmicos da linguagem principal tornam as bases de código numéricas grandes e colaborativas mais difíceis de raciocinar (consulte a próxima seção).


Tipos de Perl Básico

O modelo de dados fundamental da Perl se concentra em três construções:

Construção Sigil O que ela tem
Escalar $ Um único valor: número, string, referência, ou undef
Array @ Uma lista ordenada de escalares, indexada por inteiro
Hash % Uma coleção não ordenada de valores escalares com chave por string

Todo o resto — objetos, fechamentos, estruturas de dados complexas — é construído a partir dessas três primitivas via referências (\@array, \%hash, sub { ... }).

Este modelo é extraordinariamente flexível. Uma única matriz pode conter números inteiros, números de ponto flutuante, strings e referências aninhadas simultaneamente. Essa flexibilidade é exatamente o que fez de Perl a linguagem dominante de administração de sistemas e web-script por duas décadas.

O problema da hierarquia de cache

As CPUs modernas atingem o throughput de pico somente quando os dados fluem pelo cache L1/L2/L3 em blocos grandes e contíguos — uma propriedade chamada spatial locality. As matrizes perl não fornecem isso. Sob o capô, uma matriz de Perl é uma matriz C de pointers para escalar alocado por heap (SV) estruturas. Cada escalar carrega uma contagem de referência, uma tag de tipo e preenchimento – geralmente de 24 a 56 bytes por escalar em uma compilação de 64 bits. Iterar mais de um array Perl de um milhão de elementos envolve, portanto, um milhão de referências de ponteiro espalhadas pelo heap, produzindo um padrão de falha de cache que nega completamente a vantagem de velocidade dos pipelines SIMD modernos.

A concrete consequence: um produto pontual de dois vetores de 1.000 elementos escritos em Perl puro é aproximadamente 100-1000× mais lento do que a operação equivalente em um par de matrizes flutuantes PDL, que ocupam duas regiões de memória plana de 4.000 bytes que se encaixam confortavelmente no cache L1.

Contraste com R

R ocupa um meio-termo curioso. Como Perl, é uma linguagem dinâmica, interpretada - variáveis são recipientes não digitados, funções são valores de primeira classe, e o REPL interativo é o ambiente de desenvolvimento primário. R ainda tem análogos diretos aos três tipos principais de Perl:

Conceito Perl Analógico R
$scalar vetor atômico length-1 ou escalar-na-lista
@array list()
%hash nomeado list()
Referência (\@arr) R não usa referências explícitas; copiar-em-modificar semântica em vez

Mas o tipo de cavalo de trabalho de R, ou seja, o vetor atômico não tem uma contrapartida direta de Perl. Um vetor atômico R é um bloco de memória contíguo e homogeneamente digitado – exatamente o layout que um cache de CPU recompensa. Cada escalar embutido em R é na verdade um vetor atômico de comprimento-1; não há “escalável” fora dos vetores atômicos.

Essa escolha de design significa que o código R opera naturalmente em vetores de milhões de duplas com throughput de nível BLAS, sem que o usuário escreva um único loop ou aloque um especial. “matriz” objeto.

Os tipos atômicos de R são:

Tipo atómico R Armazenamento Equivalente C
logical 4 bytes/elemento int (com NA sentinela)
integer 4 bytes/elemento int32_t
double 8 bytes/elemento double
complex 16 bytes/elemento _Complex double
character ponteiro para CHARSXP char * (internado)
raw 1 byte/elemento uint8_t

R also defines higher-level structures built on atomic vectors:

  • matriz — um vetor atômico 2D com um dim atributo.
  • array — um vetor atômico N-D com um dim atributo.
  • data.frame — uma lista nomeada de vetores atômicos de igual comprimento; a língua franca de
    dados tabulares em R.
  • fator — um vetor inteiro com um levels atributo; codifica dados categóricos.

The lesson: O desempenho de computação da R quando usado em aplicações estatísticas e de ciência de dados flui diretamente de seus vetores atômicos contíguos. O caminho equivalente de Perl para o desempenho é uma extensão (que também é um stand alone). matlab como o ambiente), a Linguagem de Dados Perl PDL.


Threading e SIMD

Uma das características mais distintivas do PDL é o encadeamento implícito: as operações são transmitidas automaticamente por dimensões extras, eliminando loops explícitos no código do usuário e delegando loops internos a kernel C ou Fortran otimizados. Combinado com set_autopthread_targ(N), o PDL paralelizará automaticamente as fatias independentes N Threads do SO — sem que o usuário escreva um único fork ou Thread::Queue ligar.

Valores inválidos

PDL tem um conceito embutido de valores incorretos (PDL::Bad), diretamente análogo ao R’s NA. Um ndarray pode ser sinalizado como “valor incorreto ciente”, e as operações PDL propagam a maldade corretamente por meio de aritmética, estatística e E/S.


  1. Comparação de Tipos: Perl, PDL e R Side-by-Side

A tabela abaixo mapeia cada tipo R comumente usado para suas contrapartes Perl e PDL mais próximas, destacando onde as três línguas concordam, diferem ou se complementam.

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 Dois Três

Principais conclusões

  • Para dados numéricos e homogêneos puros (vetores, matrizes, tensores), as matrizes de PDL e os vetores atômicos R são funcionalmente equivalentes e comparativamente eficientes.

  • Para dados tabulares heterogêneos (tipos mistos, colunas de string, fatores), R’s data.frame é mais ergonômico; Perl normalmente usa um hash de arrays ou um módulo dedicado, como Data::Frame ou PDL::IO::CSV.

  • Para texto, estruturas irregulares e cola do sistema, os tipos nativos do Perl são superiores ao R e ao Python.

  • A combinação Perl+PDL, portanto, fornece a união do que R oferece como uma linguagem estatística e o que Perl oferece como uma linguagem de sistemas - ao custo de uma curva de aprendizagem mais íngreme e ferramentas estatísticas menos prontas para uso.

No entanto, a combinação de Perl+PDL+R (com o último usado como um componente, ou instrumentalizado via Perl)


  1. Roteiro: O que o resto desta série cobre

Esta série documenta a construção de um mecanismo de banco de dados vetorial criado no Perl5 + PDL do zero. Bancos de dados vetoriais sustentam pipelines modernos de geração aumentada de recuperação (RAG), pesquisa semântica e sistemas de recomendação de vizinhos mais próximos. Implementar um dos primeiros princípios é um excelente veículo para demonstrar as capacidades numéricas do PDL juntamente com os pontos fortes de programação de sistemas da Perl.

O diretório co-desenvolvido ao lado desses posts contém os seguintes componentes, cada um dos quais será objeto de um ou mais posts dedicados que farão referência a arquivos em um repositório dedicado.

Post 1 — Serialização e E/S: o VectorIO módulo

Arquivo: VectorIO.pm

O motor armazena vetores como bolhas binárias embaladas dentro MessagePack cargas úteis. Este post cobre:

  • Projetando um módulo com uma limpeza ExporterAPI pública baseada em use v5.40.

  • Ajudantes de validação que impõem a correção do esquema nos limites do sistema.

    Post 2 — Simulando um banco de dados vetorial

Arquivo: simulate_vectorDB.pl

Para podermos pesquisar um banco de dados, precisamos de um. Este post mostra:

  • Gerando vetores flutuantes aleatórios reprodutíveis com PDL::random.

  • Usando GetOpt::Long para análise de opção CLI ergonômica.

  • Escrevendo um --seedSimulação controlada que produz bancos de dados idênticos em todas as execuções — essencial para o benchmarking.

    Post 3 — Benchmarking: o timing_DB Módulo

Arquivo: timing_DB.pm

As reivindicações de desempenho exigem medição. Este post apresenta:

  • Um arnês de benchmarking reutilizável Perl construído em Time::HiRes.

  • Metodologia para comparações justas entre as implementações Perl/PDL e R.

  • Interpretação de throughput (vetores/segundo) vs. latência (ms/consulta) para diferentes tamanhos de carga de trabalho.

    Post 4 — K-Means Clustering com PDL::Stats::Kmeans

Arquivo: kmeans.pl

K-means clustering é a espinha dorsal da abordagem de índice de arquivo invertido (IVF) para aproximar a pesquisa mais próxima. Este post cobre:

  • O PDL::Stats::Kmeans interface e seu contrato de devolução (centroid, cluster, n, R2, ss).

  • Interpretando o [obs × clusters] máscara de associação retornada por run_kmeans.

  • Comparando Perl/PDL k-means centroids contra R’s kmeans() e ClusterR::MiniBatchKmeans() para validar a correção numérica.

    Post 6 — Pesquisa de Índice de Arquivo Invertido (IVF)

Arquivo: compare_ivf_search.pl

Com os centroides na mão podemos particionar o banco de dados e realizar uma pesquisa sub-linear aproximada mais próxima do vizinho. Este post cobre:

  • Building the inverted lists: mapeando cada vetor de banco de dados para seu centroide mais próximo.

  • O unpack_inverted_lists auxiliar em VectorIO.

  • Querying: encontrar os centroides mais próximos do top-K e, em seguida, pesquisar apenas essas listas.

  • Compensações de precisão vs. velocidade, pois o número de listas investigadas varia.

    Post 7 — Validando Contra R: Correção Numérica e Pipelines de Linguagem Cruzada

Arquivos: 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:

  • Exportar resultados PDL para CSV e lê-los em R para validação independente.
  • Usando ggplot2 para visualizar coordenadas do centroide de ambos os idiomas simultaneamente.
  • Um padrão de fluxo de trabalho para “computar em Perl, visualizar em R” que aproveita os pontos fortes de ambos os ecossistemas.

Next up — Post 1: Serialização e E/S com VectorIO.pm


As CPUs modernas têm vários níveis de memória rápida no chip chamados caches (L1, L2, L3) que ficam entre os núcleos do processador e a RAM principal. L1 é o menor (normalmente de 32 a 64 KB por núcleo) e mais rápido (latência de ciclos de relógio de 1 a 4); L2 é maior (256 KB a 1 MB) e um pouco mais lento; L3 é compartilhado entre núcleos (4 a 64 MB) com maior latência ainda. A RAM principal fica mais distante na latência de 60 a 100 ns - aproximadamente 200 vezes mais lenta que a L1.

Quando um cálculo toca a memória em um padrão previsível e contíguo, o hardware prefetcher pode carregar dados futuros em L1/L2 antes de ser necessário, alcançando um throughput de quase pico. A busca dispersa de ponteiros (como percorrer uma matriz Perl de escalares alocados por heap) derrota a pré-busca, interrompendo a CPU enquanto espera que cada falha de cache seja resolvida da RAM.

Sandbox: diagrama wardley-beta da sereia SSI

wardley-beta title Jamstack Wiki Value Chain anchor Business [0.95, 0.35] component Cloud Hosting [0.80, 0.80] component Agentic AI [0.25, 0.35] component Jamstack Wiki [0.70, 0.55] component Markdown Editor [0.50, 0.60] component Version Control [0.05, 0.65] component SSG [0.60, 0.80] Business -> Jamstack Wiki Agentic AI -> Markdown Editor Jamstack Wiki -> Cloud Hosting Jamstack Wiki -> Markdown Editor Agentic AI -> Version Control SSG -> Jamstack Wiki evolve Version Control 0.80 evolve Agentic AI 0.55 note "Standardized Version Control allows Agentic AI to evolve faster" [0.15, 0.30]