Como otimizamos as Coleções do Delphi e aceleramos o build em 60%

Introdução
Seção intitulada “Introdução”Todo desenvolvedor Delphi conhece o custo das Generics.Collections. Elas mudaram completamente o jogo quando introduzidas, mas também trouxeram um “imposto” na maioria das vezes invisível: Code Bloat (inchaço de código) e tempos de compilação que testam nossa paciência diariamente. No Project Dext, decidimos que precisávamos de algo mais rápido, mais inteligente e, acima de tudo, mais produtivo.
A Grande Vitória: Produtividade e “Code Folding” ⚡
Seção intitulada “A Grande Vitória: Produtividade e “Code Folding” ⚡”O maior vilão da produtividade em grandes projetos Delphi é o tempo de inatividade esperando o compilador terminar o trabalho. No início do processo com base inicial de projetos Dext em larga escala, um build full durava cerca de 8 minutos e 36 segundos.
O problema central é a arquitetura de compilação de Generics: o compilador do Delphi precisa gerar o código em binário separadamente e na íntegra para cada especialização de genérico instanciado. Num teste de estresse moderno no backend do Dext, nos deparamos com fluxos simultâneos de:
- 500 especializações de IList
- 1.500 especializações de TDictionary<K,V>
- Total: 2.000 especializações completas duplicando código gerado
E como resolvemos isso? Implementando o padrão de Code Folding Binário, em que essas centenas de listas e coleções passam a compartilhar um único motor central (TRawList), que foi modelado para atuar silenciosamente e com segurança sobre fatias de memória bruta.
Isso desabou nosso tempo de compilação de forma colossal. Mesmo após adicionarmos outras camadas agressivamente voltadas para tempo de execução (que custaram cerca de 1 minuto a mais do compilador), esse grande projeto estabilizou num build final de apenas 3 minutos e 36 segundos.
O Veredito: Saímos de quase 9 minutos para meros 3.5 minutos de espera. É mais que o dobro em produtividade diária em longo prazo e um alívio ao time de desenvolvedores, sem abrir mão de um binário sniper veloz.
A Arquitetura: O Sniper de Performance 🎯
Seção intitulada “A Arquitetura: O Sniper de Performance 🎯”
Atingir picos máximos de fluidez requer refazer as coisas que já não escalam. Adotamos três grandes pilares de engenharia nas dezenas de implementações internas de busca e indexação das Collections:
- Recursão Especializada: Removemos comandos e bifurcações
casedos inner loops nos algoritmos de ordenação. O motor estabelece trilhas de processamento diretas paraInteger,FloateString. O processador foca agora na linha de chegada, sem decisões custosas pelo caminho. - Hybrid Sort (QuickSort + Insertion Sort): Quando a lista fica num estrato pequeno de fatias e blocos, abandonamos forçosamente a recursão pesada do algoritmo
QuickSorte delegamos para algoritmos amigáveis à CPU cache comoInsertion Sortfocado de forma linear. - Mirroring de Flags: O Dext refaz de forma brilhante o comportamento das flags vitais: o wrapper superior
TList<T>carrega atributos espelho, evitando que interações e loops perguntem a todo momento peloTypeInfo()dos objetos gerenciados, economizando ciclos brutais vitais.
A Etapa Decisiva: Dext vs RTL 📊
Seção intitulada “A Etapa Decisiva: Dext vs RTL 📊”Com os motores regulados, nossos testes atestam as vitórias. Estes benchmarks são executados em Single-Thread e em processos isolados por completo (sem interrupções como antivírus e background agressivo).
Tipos Primitivos (Velocidade Pura)
Seção intitulada “Tipos Primitivos (Velocidade Pura)”| Operação | Cenário | RTL (ms) | Dext (ms) | Ratio % |
|---|---|---|---|---|
| List Sort | 10k Integers | 0,54ms | 0,07ms | 14,6% (6.8x Mais Rápido!) |
| IndexOf | 100 Inteiros | 0,008ms | 0,0002ms | 2,4% (42x Mais Rápido!) |
| Dictionary Lookup | 100k itens | 6,61ms | 1,00ms | 15,2% (6.6x Mais Rápido!) |
| List Add | 100k Integers | 0,61ms | 0,26ms | 43,2% (2.3x Mais Rápido!) |
Tipos Gerenciados e Objetos (Eficiência com Segurança)
Seção intitulada “Tipos Gerenciados e Objetos (Eficiência com Segurança)”Trabalhar com referências circulares ou strings adiciona uma carga severa de Reference Counting. Ainda lidando com isso o Dext manteve o fôlego impecável:
| Operação | Cenário | RTL (ms) | Dext (ms) | Ratio % |
|---|---|---|---|---|
| List Add | 100k Objetos | 5,95ms | 4,42ms | 74,3% (Mais Rápido!) |
| List Sort | 100k Strings | 33,29ms | 28,30ms | 85,0% (Mais Rápido!) |
| Iteration (for-in) | 10k Strings | 0,16ms | 0,14ms | 88,1% (Mais Rápido!) |
| Add/Populate | 100k Strings | 9,81ms | 9,17ms | 93,4% (Mais Rápido!) |
[!TIP] Em cenários vitais nas Strings e processamento pesado de referências gerenciadas de memórias (onde o custo da arquitetura do Windows/SO prevalece), a RTL cai pelo overhead total. O Dext demonstra que também prevalece nas coleções gerenciadas com precisão e tempo curto.
Concorrência Moderna: Canais e Operações Lock-Free 🚀
Seção intitulada “Concorrência Moderna: Canais e Operações Lock-Free 🚀”Bases robustas necessitam distribuir cargas em multiplos processos sem dor ou atritos massivos. A maior parte das bibliotecas no ambiente de coleções contam com implementações dependentes massivamente de uso de bloqueios via TCriticalSection ou envoltórios arcaicos através de TMonitor. O maior problema? Nos servidores poderosos de backend em múltiplos cores o cenário vira atrito que restringe agressivamente o throughput real escalado.
No Dext, levamos a base paralela a um status totalmente novo. Desenvolvemos com inspiração nativa na linguagem Go (Golang) adotando Canais de Transmissão (Channels) e implementações estritas e poderosas de coleções orientadas sem interrupções por travamentos manuais (Lock-Free).

Canais de Altíssimo Rendimento (IChannel<T>)
Seção intitulada “Canais de Altíssimo Rendimento (IChannel<T>)”Você pode acelerar a taxa isolada de processamento, porém entupir filas retém desempenho global. O IChannel<T> proporciona uma estrutura superior sem as travas:
- Zero Lock Contention: Fluidez transparente entre produtores das ordens/ações e o pool responsável por consumir dados.
- Backpressure Nativo de Fábrica: Permissões em buffers base de uso limitados (
Bounded Channels) retém a força do tráfego desordenado, não permitindo que threads produtoras muito rápidas congestionem o servidor e inundem em vazão incontrolada a infra. - Desenho Orgânico e Linear: Código assíncrono muito familiar ao linear.
var Chan: IChannel<TOrder>;begin Chan := TChannel<TOrder>.CreateBounded(100);
// Thread de Produção TTask.Run(procedure begin while Processing do Chan.Write(ProduceOrder); end);
// Thread de Consumo (Sem locks manuais, sem dor de cabeça!) TTask.Run(procedure begin while Chan.IsOpen do ProcessOrder(Chan.Read); end);end;A abordagem com Locks não escala de maneira progressiva (A partir de 4 clusters ou requisições concorrentes ela frequentemente sufoca em paradas em filas do Windows Memory Manager). Já os Channels no ecossistema Dext progridem organicamente mantendo linhas rentáveis em ambientes server-side e hardwares escalares.
Estabilidade Absoluta: 140 Testes Unitários 🛡️
Seção intitulada “Estabilidade Absoluta: 140 Testes Unitários 🛡️”Comprovar promessas é complexo, testar e mantê-las sob checagens constantes é mais realístico. O núcleo novo base no código da Coleção do Dext já iniciou em formato inabalável de entrega:
- 140 testes automatizados engatilhados e aprovando em 100% dos fluxos diários.
- Rígido e extremo processamento contínuo em Memory Leaks sobre ciclos da vida da memória e dos objetos gerenciáveis contendo escopos limitados.
- Integração global e certificações do
Channelssem falha de trânsito em Concorrência.
Expressividade Fluente: Performance Transparente 🧩
Seção intitulada “Expressividade Fluente: Performance Transparente 🧩”Performance máxima da RTL sempre pareceu exigir linguajar rústico nas telas ou manipulação manual crua (com ponteiros perigosos e loops confusos). Mas nossa visão preza código expressivo, por estarmos num runtime altamente avançado em tempo de compilação como Prototype.Entity no Dext, onde sintaxe fluente tem retorno imbatível na precisão gerada:
var Clients: IList<TClient>;begin var c := Prototype.Entity<TClient>;
// Sintaxe Fluente Dext: Leitura direta aos olhos, compilado sniper na máquina Clients := Customers .Where(c.Balance > 1000000) .Sort(c.Balance.Asc) .ToList;end;Conclusão
Seção intitulada “Conclusão”A reconstrução total do Dext.Collections tem se mostrado a via correta e demonstra de maneira inequívoca a viabilidade técnica e arquitetural e a melhoria que frameworks maduros devem alcançar ao migrar componentes vitais internos e trocar o confortável e lento do ecossistema legado, pelo disruptivo incisivo. Tivemos que processar com builds apenas 1 minuto mais lentos em tempo de execução global na compilação face à nossa v1 inicial interna pra atingirmos uma revolução de centenas de macros e ganho na entrega.
No final, entregamos uma engenharia pra backend que vai permitir sua aplicação engolir filas simultâneas gigantes sem travar.
Essa implementação de coleções nativa que mostrei aqui e a expressividade delas são apenas o começo. Começaremos a adotar integralmente as extensões dessa infraestrutura na plataforma Dext e vamos introduzir mais melhorias cirúrgicas focadas no gargalo de manipulação e escalabilidade sempre onde for viável de se adicionar, tornando nossos retornos massivos cada vez melhores.
Prontos para programar fora das contenções e travas da RTL base? Acelere no Dext. 🏁🚀
🔗 Links Úteis
Seção intitulada “🔗 Links Úteis”- 🌐 Projeto Dext Framework: Acesse a Iniciativa e Funcionalidades (Não esqueça de deixar uma estrela ⭐ no repositório!)
- 📖 Dext Book (Documentação Oficial): Acesse o Repositório do Dext Book com a Base Conhecimento
- 📚 Livro Delphi Multithreading: Conheça o guia definitivo sobre concorrência e performance (Português/Inglês)