Simon Willison usa Claude para reduzir de 67 para 19 ns a análise de números no SQLite
Um valor como “-$1,234.56” em um CSV precisa ser tratado antes de entrar em uma soma no SQLite. Simon Willison pediu ao Claude que comparasse extensões em C e Rust para essa tarefa: as primeiras versões em Rust foram mais rápidas, embora ocupassem consideravelmente mais espaço. Após a substituição do parser padrão em C, o tempo de processamento por linha com dados mistos caiu de 67 para 19 ns, contra 41–46 ns em Rust.
Processado por IA de Simon Willison; editado por Hamidun News
Você exporta pagamentos para um CSV, carrega o arquivo no SQLite e encontra “-$1,234.56” na coluna de valores. Para uma pessoa, isso é um número; para o banco de dados, é uma string que precisa ser interpretada antes das operações de soma e ordenação. Simon Willison decidiu verificar a dificuldade de adicionar uma função parse_number() para essa tarefa e pediu ao Claude que comparasse implementações em C e Rust.
O resultado foi um experimento de engenharia pequeno, mas útil. De início, Rust ganhou em velocidade, e C, no tamanho da extensão. Depois, Willison pediu a substituição da função de análise de números em C, e o cenário mudou: com dados mistos, o tempo de processamento por linha caiu de 67 para 19 nanossegundos. A lição prática está em como um trecho específico de código pode mudar o resultado de uma comparação entre linguagens.
Uma função SQL em vez de tratar os dados em cada consulta
A tarefa de parse_number() é simples: remover vírgulas, símbolos monetários e sinais de porcentagem de uma string, considerar um eventual sinal de menos no início e retornar um valor numérico. Se a string não puder ser interpretada, a função deve retornar NULL. Esse comportamento permite transferir o tratamento repetitivo dos dados para uma extensão do SQLite e depois usar o resultado nos cálculos.
Por exemplo, ao remover o símbolo de dólar e o separador de milhares de “-$1,234.56”, o resultado é -1234.56. Esse valor pode então ser somado a outros pagamentos ou ordenado como um número. O desenvolvedor deixa de precisar montar novamente uma sequência de substituições de texto em cada consulta.
Porcentagens exigem regras próprias. No pedido original, Willison propôs remover o sinal de porcentagem. Mas cada produto precisa decidir se “12.5%” representa o número 12.5 ou a fração 0.125. A correção dos cálculos posteriores depende dessa decisão. A velocidade de interpretação de uma string, por si só, não toma essa decisão pela equipe.
Por que Rust foi mais rápido no início
Claude preparou versões da extensão em C e com duas bibliotecas de Rust: rusqlite e sqlite-loadable-rs. Segundo Willison, a extensão compilada em C ocupava 14 KB. As versões em Rust ocupavam 321 e 298 KB, respectivamente. Para um pequeno utilitário embarcado, essa diferença pode ser relevante.
No entanto, a primeira versão em C era mais lenta. Com dados mistos, seu custo adicional de processamento era de 67 ns por linha, enquanto as versões em Rust registravam 46 e 41 ns. Willison atribuiu a diferença à análise dos números: o mecanismo usado em Rust era mais rápido que a função padrão strtod de C.
O pedido seguinte ao Claude foi mais específico: escrever uma função própria em C para interpretar números decimais que pudesse igualar ou superar Rust. Após essa substituição, a versão em C registrou 19 ns com dados mistos, 16 ns com números inteiros e 18 ns com frações decimais.
Para comparação, com frações decimais a versão original em C precisava de 106 ns, enquanto as versões em Rust levavam 55 e 47 ns. Todas as medições citadas correspondem a um experimento com dois milhões de linhas. Elas representam o custo adicional de processamento por linha, portanto esses números não podem ser convertidos diretamente no tempo de execução de uma consulta SQL inteira.
O que verificar antes de usar
O experimento mostra por que escolher uma linguagem com base em um único benchmark pode facilmente levar a uma decisão precipitada. Aqui, substituir uma única função mudou bastante o resultado. Para uma tarefa própria, é mais útil identificar primeiro a operação que consome mais tempo e depois comparar alternativas com os mesmos dados e os mesmos requisitos para o resultado.
O ganho de velocidade, por si só, também não demonstra que um parser próprio substitui completamente o padrão. Antes de usá-lo, vale verificar os formatos aceitos, valores muito grandes, arredondamento, espaços em branco e strings com caracteres inválidos. Se o produto aceita valores de diferentes países, também serão necessárias regras para a vírgula decimal e os separadores de milhares. Esses são aspectos a verificar na implementação, e não falhas comprovadas do código publicado.
Willison também pediu ao Claude que documentasse a pesquisa e publicou o resultado no repositório simonw/research. Para os desenvolvedores, esse é um ponto de partida: repetir as medições com seus próprios dados exportados, verificar a correção e só então escolher uma implementação. Neste caso, Claude ajudou a avançar rapidamente de uma ideia para várias alternativas medidas; a adequação de cada uma ainda precisa ser avaliada de acordo com os requisitos do sistema específico.
- 9 de nov. de 2026robots.txt não impede o treinamento de IA: quais bots bloquear para continuar nas respostas
- 9 de nov. de 2026Automattic lança Spacefast: hospedagem com banco de dados e autenticação para vibe coding
- 9 de nov. de 2026Equipe da Dokumenterra encarrega Claude de escrever testes automatizados em cinco horas
- 9 de nov. de 2026Simon Willison recolhe descrições de PR geradas por IA: os principais pontos em 1 parágrafo
Perguntas frequentes sobre a notícia
O que se sabe sobre Uma função SQL em vez de tratar os dados em cada consulta?
A tarefa de parse_number() é simples: remover vírgulas, símbolos monetários e sinais de porcentagem de uma string, considerar um eventual sinal de menos no início e retornar um valor numérico. Se a string não puder ser interpretada, a função deve retornar NULL. Esse comportamento permite transferir o tratamento repetitivo dos dados para uma extensão do SQLite e depois usar o resultado nos cálculos. Por exemplo, ao remover o símbolo de dólar e o separador de milhares de “-$1,234.56”, o resultado é -1234.56.
Por que Rust foi mais rápido no início?
Claude preparou versões da extensão em C e com duas bibliotecas de Rust: rusqlite e sqlite-loadable-rs. Segundo Willison, a extensão compilada em C ocupava 14 KB. As versões em Rust ocupavam 321 e 298 KB, respectivamente. Para um pequeno utilitário embarcado, essa diferença pode ser relevante. No entanto, a primeira versão em C era mais lenta. Com dados mistos, seu custo adicional de processamento era de 67 ns por linha, enquanto as versões em Rust registravam 46 e 41 ns.
O que verificar antes de usar?
O experimento mostra por que escolher uma linguagem com base em um único benchmark pode facilmente levar a uma decisão precipitada. Aqui, substituir uma única função mudou bastante o resultado. Para uma tarefa própria, é mais útil identificar primeiro a operação que consome mais tempo e depois comparar alternativas com os mesmos dados e os mesmos requisitos para o resultado. O ganho de velocidade, por si só, também não demonstra que um parser próprio substitui completamente o padrão.
Test Frontier LLMs & Autonomous Agents in One Workspace
Run Claude Opus 5.5, GPT-6, Gemini 3.1, and DeepSeek side-by-side in Nomad AI (nomadnet.ai) — unified model routing, deep research, and multimodal workflows under one subscription.
O essencial da IA — uma vez por semana
Sete histórias que realmente importaram, escolhidas a dedo. Sem ruído nem releases.
Pronto! Verifique seu e-mail para a confirmação.