Suponha que eu tenha uma if
afirmação com a return
. Do ponto de vista da eficiência, devo usar
if(A > B):
return A+1
return A-1
ou
if(A > B):
return A+1
else:
return A-1
Devo preferir um ou outro ao usar uma linguagem compilada (C) ou uma script (Python)?
python
c
performance
compiler-construction
Jorge Leitao
fonte
fonte
Respostas:
Como a
return
instrução encerra a execução da função atual, as duas formas são equivalentes (embora a segunda seja discutivelmente mais legível que a primeira).A eficiência de ambos os formulários é comparável; o código de máquina subjacente deve executar um salto se a
if
condição for falsa de qualquer maneira.Observe que o Python suporta uma sintaxe que permite usar apenas uma
return
instrução no seu caso:fonte
return (A>B)?A+1:A-1;
No entanto, não há absolutamente nenhum ganho no desempenho ao escrever o código dessa maneira. Tudo o que alcançamos é tornar o código ofuscado, ilegível e, em alguns casos, mais vulnerável a promoções implícitas de tipo.<
é uma prática ruim porque-1 < 1u
produz um resultado inesperado.-1 < 1u
, o que eu duvido, seria fácil identificar o bug. Muitas pessoas escreveriam alguma versão do código que eu publiquei. Vi esses bugs com muita frequência no código de produção para confiar no operador?:. Também como regra geral, se o idioma fornecer duas maneiras diferentes de fazer a mesma coisa, use apenas uma delas, não escolha aleatoriamente nenhuma das duas, dependendo do seu humor.Do guia de estilo do Chromium :
Não use mais depois do retorno:
fonte
if-else-return
ramificações quase nunca são iguais (se forem, então você deve refatorar de qualquer maneira; usando umaswitch
construção ou para Python, enumerando um dict / usando um callable / etc.). Portanto, quase todosif-else-return
são casos de cláusulas de guarda e esses são sempre testáveis (zombam da expressão testada) sem oelse
.Em relação ao estilo de codificação:
A maioria dos padrões de codificação, independentemente do idioma, proíbe várias declarações de retorno de uma única função como prática recomendada.
(Embora pessoalmente eu diria que há vários casos em que várias instruções de retorno fazem sentido: analisadores de protocolo de texto / dados, funções com amplo tratamento de erros, etc.)
O consenso de todos os padrões de codificação do setor é que a expressão deve ser escrita como:
Em relação à eficiência:
O exemplo acima e os dois exemplos na pergunta são todos equivalentes em termos de eficiência. Em todos esses casos, o código da máquina deve comparar A> B, ramificar para o cálculo A + 1 ou A-1 e armazenar o resultado disso em um registro da CPU ou na pilha.
EDIT:
Fontes:
fonte
return
onde fica claro é a maneira idiomática de fazê-lo no Python.Com qualquer compilador sensato, você não deve observar nenhuma diferença; eles devem ser compilados em código de máquina idêntico, pois são equivalentes.
fonte
Esta é uma questão de estilo (ou preferência), pois o intérprete não se importa. Pessoalmente, eu tentaria não fazer a declaração final de uma função que retorna um valor em um nível de recuo diferente da base da função. O resto do exemplo 1 obscurece, mesmo que ligeiramente, onde está o final da função.
Por preferência eu uso:
Como ele obedece à boa convenção de ter uma única declaração de retorno como a última declaração na função (como já mencionado) e ao bom paradigma de programação funcional de evitar resultados intermediários no estilo imperativo.
Para funções mais complexas, prefiro dividir a função em várias subfunções para evitar retornos prematuros, se possível. Caso contrário, volto a usar uma variável de estilo imperativa chamada rval. Tento não usar várias instruções de retorno, a menos que a função seja trivial ou a declaração de retorno antes do final seja resultado de um erro. O retorno prematuro destaca o fato de que você não pode continuar. Para funções complexas projetadas para ramificar-se em múltiplas subfunções, tento codificá-las como instruções de caso (orientadas por um ditado, por exemplo).
Alguns pôsteres mencionaram a velocidade de operação. A velocidade do tempo de execução é secundária para mim, pois se você precisar de velocidade de execução, o Python não é a melhor linguagem para usar. Eu uso o Python como a eficiência da codificação (isto é, escrever código sem erros) que é importante para mim.
fonte
var n = 1 if (A > B) else -1
return A+n
Pessoalmente, evito
else
bloqueios quando possível. Veja a campanha anti-seAlém disso, eles não cobram 'extra' pela linha, você sabe: p
"Simples é melhor que complexo" e "Legibilidade é rei"
fonte
dict
s para evitar diferenças é uma péssima idéia em termos de desempenho.A versão A é mais simples e é por isso que eu a usaria.
E se você ativar todos os avisos do compilador em Java, receberá um aviso na segunda versão porque é desnecessário e aumenta a complexidade do código.
fonte
Eu sei que a pergunta está marcada como python, mas menciona linguagens dinâmicas, então pensei em mencionar que, em ruby, a instrução if realmente tem um tipo de retorno para que você possa fazer algo como
Ou porque também possui retorno implícito simplesmente
que contorna a questão do estilo de não ter vários retornos muito bem.
fonte