![Um bate-papo com os copresidentes da CloudNativeSecurityCon North America 2024](https://optimuscloud.com.br/wp-content/uploads/2024/06/1718385726_Um-bate-papo-com-os-copresidentes-da-CloudNativeSecurityCon-North-America-2024-150x150.jpg)
Um bate-papo com os copresidentes da CloudNativeSecurityCon North America 2024
14 de junho de 2024![Featued image for: Broadcom: Investing in Mainframe Success Beyond Code](https://optimuscloud.com.br/wp-content/uploads/2024/06/1718390643_Broadcom-Investindo-no-sucesso-do-mainframe-alem-do-codigo-150x150.jpg)
Broadcom: Investindo no sucesso do mainframe além do código
14 de junho de 2024PITTSBURGH – “Em Python, você paga no tempo de execução”, diz um antigo aforismo do Python.
A linguagem de programação Python conquistou reputação por ser um tanto complicada, uma boa linguagem inicial, mas sem a velocidade de suas irmãs mais sofisticadas.
Mesmo assim, muitas das palestras na PyCon US 2024 deste ano, realizada no mês passado em Pittsburgh, mostraram como os pesquisadores estão ampliando as fronteiras da linguagem.
Compile código Python para matemática mais rápida
![Saksham Sharma na Pycon 2024.](https://optimuscloud.com.br/wp-content/uploads/2024/06/1718389325_553_Por-que-o-Python-e-tao-lento-e-o-que.jpg)
Saksham Sharma na Pycon 2024.
Como diretor de Tecnologia de Pesquisa Quantitativa na Tower Research Capital, Saksham Sharma constrói sistemas de negociação em C++. “Gosto de código rápido”, disse ele no início de sua palestra.
Ele gostaria de trazer um pouco desse entusiasmo para Python.
Python é uma linguagem interpretada (embora a implementação de referência do CPython do próprio Python seja, na verdade, escrita em C). O interpretador converte o código-fonte em um bytecode eficiente de uns e zeros. Em seguida, ele executa o código-fonte diretamente e cria um estado interno do programa a partir de todos os objetos e variáveis à medida que são lidos (em vez de compilados em código de máquina antecipadamente, como é feito por um compilador).
“Portanto, estamos passando por um monte de indiretas aqui, então as coisas podem ficar lentas”, disse Sharma.
Para Python, mesmo uma simples instrução para somar dois números pode resultar em mais de 500 instruções para a própria CPU, incluindo não apenas a adição em si, mas todas as instruções de suporte, como escrever a resposta para um novo objeto.
Cython, um compilador estático otimizado para Python, permite escrever código em C, compilá-lo antecipadamente e, em seguida, usar os resultados em seu programa Python.
“Você pode construir bibliotecas e utilitários externos integrados ao seu intérprete, e eles podem interagir com o estado interno do seu intérprete”, disse Sharma. “Se você tem uma função que escreveu à vista em seu intérprete, pode ser configurado para chamar essa função.”
Assim, o código Python para adicionar duas variáveis…
Pode ser renderizado para Cython assim:
Mais digitação para o desenvolvedor, mas menos trabalho para o compilador.
Sharma descobriu que em sua própria máquina, uma operação adicional como essa poderia levar 70 nanossegundos com Python, mas cerca de 14 nanossegundos com Cython.
“Cython definitivamente tornou isso mais rápido porque o intérprete não está mais em cena”, disse Sharma. Por exemplo, cada vez que o intérprete precisa adicionar duas variáveis, ele deve verificar o tipo de cada variável. Mas se você já sabe qual é o tipo, por que não eliminar totalmente essa verificação? Isto é o que os programadores fazem quando declaram um tipo de variável no código.
“O código digitado pode ser muito, muito mais rápido”, disse Sharma.
![Um slide resumindo o trabalho de Saksham Sharma.](https://optimuscloud.com.br/wp-content/uploads/2024/06/1718389325_858_Por-que-o-Python-e-tao-lento-e-o-que.jpg)
Cython pode acelerar loops internos (Saksham Sharma)
Um Python que amplia com digitação estática
![Uma foto de Antonio Cuni.](https://optimuscloud.com.br/wp-content/uploads/2024/06/1718389325_909_Por-que-o-Python-e-tao-lento-e-o-que.jpg)
Antonio Cuni da Anaconda.
Como Sharma apontou na palestra anterior, há muito a ganhar com a digitação estática em Python. Com a digitação estática, você define que tipo de dados é uma variável. É uma corda? um número inteiro? Uma matriz? Leva tempo para o intérprete descobrir tudo isso.
Em sua palestra, o engenheiro principal de software da Anaconda, Antonio Cuni, apresentou o SPy, um novo subconjunto do Python que requer digitação estática. O objetivo é oferecer a velocidade de C ou C++, mantendo a sensação amigável do próprio Python.
Cuni explicou que o Python precisa fazer muitas coisas antes de executar as instruções. Também como Sharma, Cuni apontou que com uma “linguagem de baixo nível, você geralmente faz menos coisas em tempo de execução”.
Antes de poder executar a lógica, o interpretador Python deve encontrar todas as ferramentas, como ferramentas e bibliotecas, para executar a própria lógica. Esse estágio intermediário do trabalho pode levar muito tempo.
A boa notícia é que muito desse trabalho pode ser feito antecipadamente, na fase de compilação.
Com o SPy, todas as constantes globais — como classes, módulos e dados globais — são congeladas como “imutáveis” e podem ser otimizadas (graças à sua digitação) com um compilador just-in-time (JIT).
Atualmente, Cuni está trabalhando na implementação do SPy, seja como uma extensão do CPython, ou com seu próprio compilador JIT. Ele também está procurando uma versão que possa ser executada no WebAssembly.
![Um slide da palestra de Cuni comparando compilação vs. interpretação.,](https://optimuscloud.com.br/wp-content/uploads/2024/06/1718389325_305_Por-que-o-Python-e-tao-lento-e-o-que.jpg)
Compilar vs. Intérprete (Antonio Cuni)
Extensões C, mas vinculadas estaticamente
Loren Arthur, gerente de meta engenharia, também demonstrou em sua palestra que reescrever funções de processamento pesado em C pode economizar consideravelmente e aumentar o desempenho – mas você deve ter cuidado com a forma como elas são carregadas no programa.
![](https://optimuscloud.com.br/wp-content/uploads/2024/06/1718389325_556_Por-que-o-Python-e-tao-lento-e-o-que.jpg)
Loren Artur
O módulo AC importado para o Python pode, em sua própria demonstração, reduzir a mastigação dos dados em um arquivo de amostra de 4 segundos – que é o tempo que o código Python normal levaria para mastigar – até quase meio segundo.
Parece minúsculo, é claro. Mas para uma operação do tamanho do Meta isso soma. A conversão da funcionalidade Python em código C mais ágil para 90.000 aplicativos Python economizou 5.000 horas por semana para os engenheiros da Meta, apenas graças à melhoria da velocidade de construção.
Isso foi ótimo. O Instagram construiu milhares de extensões C para levar as coisas adiante.
Mas então! O gigante da mídia social enfrentou outro problema. O tempo de importação para extensões C aumentava negativamente à medida que elas eram incluídas em uma compilação. Estranho porque a maioria desses módulos são bem pequenos, talvez contendo um único método e um retorno de string neles.
Usando Callgrind (parte do conjunto Valgrind de ferramentas de análise dinâmica), Arthur descobriu que uma função Python, chamada abrirleva 92% do tempo abrindo o objeto compartilhado.
“Carregar objetos compartilhados é caro, especialmente quando se chega a números muito grandes”, disse ele.
Meta encontrou a resposta na forma de extensões C incorporadas, para fazer links estáticos em vez de links dinâmicos com o objeto compartilhado. Em vez de chamar um objeto compartilhado, o código c é copiado diretamente no arquivo executável.
Objetos que vivem para sempre
![Vinícius Gubiani Ferreira na Pycon 2024](https://optimuscloud.com.br/wp-content/uploads/2024/06/1718389325_879_Por-que-o-Python-e-tao-lento-e-o-que.jpg)
Vinícius Gubiani Ferreira explica uma nova forma de fazer programação multicore, na Pycon 2024.
O Global Interpreter Lock (GIL), que impede que vários processos executem código Python ao mesmo tempo, não começou a ser o vilão dessa história, na visão de Vinícius Gubiani Ferreira, engenheiro de software líder da equipe da Azion Technologies.
Em vez disso, GIL foi o herói que permaneceu por muito tempo e se tornou um vilão.
A palestra de Ferreira discutiu o PEP 683, que buscava melhorar o consumo de memória para aplicações de grande porte. A biblioteca resultante foi incluída no Python v 3.12, lançado em outubro.
O GIL foi projetado para evitar condições de corrida, mas também impediu o Python de realizar a verdadeira computação paralela multi-core. Há trabalho para tornar o GIL opcional em Python, mas pode levar alguns anos até que ele seja estabilizado no próprio tempo de execução da linguagem.
Basicamente, tudo em Python é um objeto, explicou Ferreira. Variáveis, dicionários, funções, métodos e até instâncias: todos os objetos. Na sua forma mais básica, um objeto consiste em um tipo, uma variável e uma contagem de referência, que contabiliza o número de outros objetos que apontam para este.
Todos os objetos Python são mutáveis, mesmo aqueles marcados como imutáveis (como strings), e, em Python, a contagem de referências muda muito. Tipo, realmente muito. Na verdade, isso é problemático. Cada atualização significa que o cache é invalidado. Isso complica a bifurcação de um programa. Causa corridas de dados; as alterações podem se sobrescrever e, se o resultado for igual a zero, então Boom! O coletor de lixo apaga o objeto.
Quanto mais você dimensiona um aplicativo, mais agravados esses problemas se tornam.
A resposta é bastante fácil: crie um estado imutável onde a contagem de referência nunca mude, nomeadamente definindo recontagem para um número especificamente alto que não pode ser alterado (você poderia ter um incremento de programa até esse valor, observou Ferreira, mas levaria dias). O tempo de execução gerenciaria esses objetos superespeciais separadamente e seria responsável por desligá-los.
Melhor ainda: esses seres imortais também contornam o GIL. Portanto, eles podem ser usados em qualquer coisa e por vários threads simultaneamente.
Há uma pequena penalidade de desempenho de até 8-8% no Cpython com essa abordagem, o que não é surpreendente, visto que o tempo de execução precisa manter uma tabela separada. Mas especialmente em ambientes multiprocessadores (como o do Instagram), a melhoria de desempenho compensa.
“Você tem que medir para ver se está fazendo a coisa certa”, disse Ferreira.
Compartilhando o Imutável
![Uma foto de Yury Selivanov.](https://optimuscloud.com.br/wp-content/uploads/2024/06/1718389325_522_Por-que-o-Python-e-tao-lento-e-o-que.jpg)
Yury Selivanov sobre a construção de um serviço Python rápido usando subinterpretadores.
Outra forma de contornar o GIL é por meio de subintérpretes, tema quente no evento deste ano. Uma arquitetura de subinterpretador permite que vários intérpretes compartilhem o mesmo espaço de memória, cada um com seu próprio GIL.
Um desses orquestradores é uma estrutura Python chamada memhive que implementa um conjunto de trabalhadores de subinterpretadores, bem como um mecanismo RPC para que eles possam compartilhar dados. Ele foi apresentado na Pycon por seu criador Yury Selivanov, desenvolvedor principal do Python e CEO/cofundador do EdgeDB, em sua palestra sobre Pycon.
Selivanov iniciou sua palestra demonstrando um programa em seu laptop que usava 10 núcleos de CPU para executar 10 loops de eventos assíncronos simultaneamente. Eles compartilham o mesmo espaço de memória, de um milhão de chaves.
O que está impedindo você de fazer isso em sua própria máquina? Aquele velho vilão, GIL.
Memhive configura um subinterpretador primário que pode então gerar quantos outros subinterpretadores forem necessários.
Objetos imutáveis são um desafio e existem muitos deles em Python, como strings ou tuplas. Se quiser alterá-los, você terá que criar um novo objeto e copiar cada elemento – uma operação bastante cara, computacionalmente falando, e ainda mais quando você leva em consideração a atualização do cache.
Memhive usa uma estrutura de dados compartilhada, chamada compartilhamento de estrutura — hamt.c enterrada na biblioteca Python — onde as alterações subsequentes são capturadas, mas as partes da antiga estrutura de dados imutável são referenciadas, em vez de copiadas, economizando um trabalho considerável.
![Um diagrama de compartilhamento estruturado.](https://optimuscloud.com.br/wp-content/uploads/2024/06/1718389325_798_Por-que-o-Python-e-tao-lento-e-o-que.jpg)
Referências de compartilhamento estruturadas em vez de cópias, economizando tempo.
“Se você quiser adicionar uma chave, não precisa copiar a árvore inteira, basta criar os novos ramos que faltam e referenciar os outros”, disse Selivanov. “Portanto, se você tiver uma coleção com bilhões de chaves e quiser adicionar uma nova, basta criar alguns desses nós subjacentes e o restante poderá ser reutilizado. Você não precisa fazer nada a respeito deles.”
O compartilhamento estruturado abre a porta para o processamento paralelo, na medida em que os dados são imutáveis, permitindo que vários subinterpretadores trabalhem em paralelo no mesmo conjunto de dados.
“Como estamos usando coisas imutáveis, podemos realmente acessar a memória subjacente com segurança. sem adquirir fechaduras nem nada”, disse ele. Isso pode levar a melhorias de 6x a 150.000x na velocidade, dependendo da quantidade de cópias que estão sendo feitas.
![Slide mostrando a velocidade de cópia de grandes conjuntos de dados usando compartilhamento estruturado.](https://optimuscloud.com.br/wp-content/uploads/2024/06/1718389325_241_Por-que-o-Python-e-tao-lento-e-o-que.jpg)
Mesmo que o número de alterações aumente dramaticamente, o tempo necessário para realizá-las permanece sob controle.
Resumo
Portanto, o verdadeiro Python não é a linguagem mais rápida, e muitos desses desenvolvimentos, caso aconteçam, levarão anos para serem feitos. Mas há muito que o programador pode fazer agora, se estiver ciente da compensação entre velocidade e flexibilidade do próprio Python.
“Python é uma bela linguagem para unir diferentes partes da sua lógica de negócios. E outras linguagens são adequadas para otimizações de nível extremamente baixo, muitas vezes rápidas”, disse Sharma. “E precisamos descobrir o equilíbrio certo entre essas coisas.”
A postagem Por que o Python é tão lento (e o que está sendo feito a respeito) apareceu pela primeira vez no The New Stack.