Alguns pontos base:
- As chamadas de método Python são "caras" devido à sua natureza interpretada . Em teoria, se o seu código for simples o suficiente, a quebra do código Python terá um impacto negativo além da legibilidade e da reutilização (o que é um grande ganho para os desenvolvedores, não para os usuários ).
- O princípio de responsabilidade única (SRP) mantém o código legível, é mais fácil de testar e manter.
- O projeto tem um tipo especial de experiência em que queremos código legível, testes e desempenho de tempo.
Por exemplo, código como este, que chama vários métodos (x4), é mais lento que o seguinte, que é apenas um.
from operator import add
class Vector:
def __init__(self,list_of_3):
self.coordinates = list_of_3
def move(self,movement):
self.coordinates = list( map(add, self.coordinates, movement))
return self.coordinates
def revert(self):
self.coordinates = self.coordinates[::-1]
return self.coordinates
def get_coordinates(self):
return self.coordinates
## Operation with one vector
vec3 = Vector([1,2,3])
vec3.move([1,1,1])
vec3.revert()
vec3.get_coordinates()
Em comparação com isso:
from operator import add
def move_and_revert_and_return(vector,movement):
return list( map(add, vector, movement) )[::-1]
move_and_revert_and_return([1,2,3],[1,1,1])
Se eu devo paralelizar algo assim, é bastante objetivo que eu perco o desempenho. Mente que é apenas um exemplo; meu projeto possui várias mini-rotinas com matemática como essa - embora seja muito mais fácil trabalhar com, nossos criadores de perfil não gostam disso.
Como e onde adotamos o SRP sem comprometer o desempenho no Python, pois sua implementação inerente o afeta diretamente?
Existem soluções alternativas, como algum tipo de pré-processador que coloca as coisas em linha para o lançamento?
Ou o Python é simplesmente ruim em lidar com a quebra de código?
python
performance
single-responsibility
methods
lucasgcb
fonte
fonte
Respostas:
Infelizmente, sim, o Python é lento e há muitas histórias sobre pessoas que aumentam drasticamente o desempenho, incorporando funções e tornando seu código feio.
Existe uma solução alternativa, o Cython, que é uma versão compilada do Python e muito mais rápida.
--Edit Eu só queria abordar alguns dos comentários e outras respostas. Embora o impulso deles não seja talvez específico para python. mas otimização mais geral.
Não otimize até ter um problema e procure gargalos
Geralmente bons conselhos. Mas a suposição é que o código 'normal' geralmente é de desempenho. Nem sempre é esse o caso. Linguagens e estruturas individuais têm suas próprias idiossincrasias. Nesse caso, a função chama.
São apenas alguns milissegundos, outras coisas serão mais lentas
Se você estiver executando seu código em um computador desktop poderoso, provavelmente não se importa, desde que seu código de usuário único seja executado em alguns segundos.
Mas o código comercial tende a ser executado para vários usuários e requer mais de uma máquina para suportar a carga. Se seu código for executado duas vezes mais rápido, significa que você pode ter o dobro do número de usuários ou metade do número de máquinas.
Se você possui suas máquinas e data center, geralmente possui uma grande parcela de sobrecarga na energia da CPU. Se o seu código ficar um pouco lento, você poderá absorvê-lo, pelo menos até precisar comprar uma segunda máquina.
Nestes dias de computação em nuvem, em que você usa apenas exatamente a energia de computação necessária e não mais, há um custo direto para o código sem desempenho.
Melhorar o desempenho pode reduzir drasticamente as principais despesas de um negócio baseado em nuvem e o desempenho realmente deve estar na frente e no centro.
fonte
Muitas preocupações potenciais de desempenho não são realmente um problema na prática. O problema que você levanta pode ser um deles. No vernáculo, chamamos a preocupação com esses problemas sem provar que são problemas reais de otimização prematura.
Se você estiver escrevendo um front-end para um serviço da Web, seu desempenho não será significativamente afetado pelas chamadas de função, porque o custo do envio de dados por uma rede excede em muito o tempo necessário para efetuar uma chamada de método.
Se você estiver escrevendo um loop apertado que atualiza uma tela de vídeo sessenta vezes por segundo, isso pode ser importante. Mas nesse ponto, afirmo que você tem problemas maiores se estiver tentando usar o Python para fazer isso, um trabalho para o qual o Python provavelmente não é adequado.
Como sempre, o jeito que você descobre é medir. Execute um gerador de perfil de desempenho ou alguns timers sobre seu código. Veja se é um problema real na prática.
O princípio da responsabilidade única não é uma lei ou mandato; é uma diretriz ou princípio. O design de software é sempre sobre compensações; não há absolutos. Não é incomum trocar a legibilidade e / ou a capacidade de manutenção por velocidade; portanto, você pode ter que sacrificar o SRP no altar do desempenho. Mas não faça essa troca a menos que saiba que tem um problema de desempenho.
fonte
Primeiro, alguns esclarecimentos: Python é uma linguagem. Existem vários intérpretes diferentes que podem executar código escrito na linguagem Python. A implementação de referência (CPython) geralmente é o que está sendo referenciado quando alguém fala sobre "Python" como se fosse uma implementação, mas é importante ser preciso ao falar sobre características de desempenho, pois elas podem diferir bastante entre implementações.
Caso 1.) Se você possui um código Python puro (<= Python Language versão 3.5, 3.6 possui "suporte ao nível beta"), que depende apenas de módulos Python puros, você pode adotar o SRP em qualquer lugar e usar o PyPy para executá-lo. PyPy ( https://morepypy.blogspot.com/2019/03/pypy-v71-released-now-uses-utf-8.html ) é um interpretador Python que possui um Just in Time Compiler (JIT) e pode remover a função sobrecarga de chamada, desde que tenha tempo suficiente para "aquecer" rastreando o código executado (alguns segundos IIRC). **
Se você estiver restrito a usar o interpretador CPython, poderá extrair as funções lentas em extensões escritas em C, que serão pré-compiladas e não sofrerão nenhuma sobrecarga do interpretador. Você ainda pode usar o SRP em qualquer lugar, mas seu código será dividido entre Python e C. Se isso é melhor ou pior para a manutenção do que abandonar seletivamente o SRP, mas aderir apenas ao código Python depende da sua equipe, mas se você tiver seções críticas de desempenho do seu sem dúvida, será mais rápido do que o código Python puro mais otimizado, interpretado pelo CPython. Muitas das bibliotecas matemáticas mais rápidas do Python usam esse método (IIRC numpy e scipy). Qual é uma boa sequência para o caso 2 ...
Caso 2.) Se você possui código Python que usa extensões C (ou depende de bibliotecas que usam extensões C), o PyPy pode ou não ser útil, dependendo de como foram escritas. Consulte http://doc.pypy.org/en/latest/extending.html para obter detalhes, mas o resumo é que o CFFI possui uma sobrecarga mínima enquanto o CTypes é mais lento (o uso com o PyPy pode ser ainda mais lento que o CPython)
Cython ( https://cython.org/ ) é outra opção com a qual não tenho tanta experiência. Eu o menciono por uma questão de exaustividade, para que minha resposta possa "se sustentar por si mesma", mas não reivindique nenhum conhecimento. Pelo meu uso limitado, parecia que eu tinha que trabalhar mais para obter as mesmas melhorias de velocidade que eu poderia obter "de graça" com o PyPy, e se eu precisasse de algo melhor que o PyPy, seria igualmente fácil escrever minha própria extensão C ( que tem o benefício se eu reutilizar o código em outro local ou extrair parte dele em uma biblioteca, todo o meu código ainda poderá ser executado em qualquer interpretador Python e não é necessário que o Cython seja executado).
Estou com medo de estar "bloqueado" no Cython, enquanto qualquer código escrito para o PyPy também pode ser executado no CPython.
** Algumas notas extras sobre PyPy em produção
Tenha muito cuidado ao fazer escolhas que tenham o efeito prático de "prender você" ao PyPy em uma grande base de código. Como algumas bibliotecas de terceiros (muito populares e úteis) não são boas pelas razões mencionadas anteriormente, isso pode causar decisões muito difíceis posteriormente, se você perceber que precisa de uma dessas bibliotecas. Minha experiência é principalmente no uso do PyPy para acelerar alguns (mas não todos) microsserviços que são sensíveis ao desempenho em um ambiente de empresa, onde adiciona complexidade insignificante ao nosso ambiente de produção (já temos vários idiomas implementados, alguns com diferentes versões principais, como 2,7 vs 3.5 rodando de qualquer maneira).
Descobri que o uso do PyPy e do CPython me obrigava a escrever código regularmente, que depende apenas de garantias feitas pela própria especificação da linguagem e não de detalhes de implementação sujeitos a alterações a qualquer momento. Você pode achar que esses detalhes são um fardo extra, mas achei valioso em meu desenvolvimento profissional e acho que é "saudável" para o ecossistema Python como um todo.
fonte