A seguir, são apresentadas diretrizes aproximadas e suposições fundamentadas com base na experiência. Você deve timeit
criar um perfil do seu caso de uso concreto para obter números concretos e esses números podem ocasionalmente discordar do abaixo.
Uma compreensão de lista geralmente é um pouco mais rápida que o for
loop precisamente equivalente (que realmente cria uma lista), provavelmente porque não precisa procurar a lista e seu append
método em todas as iterações. No entanto, uma compreensão de lista ainda faz um loop no nível de bytecode:
>>> dis.dis(<the code object for `[x for x in range(10)]`>)
1 0 BUILD_LIST 0
3 LOAD_FAST 0 (.0)
>> 6 FOR_ITER 12 (to 21)
9 STORE_FAST 1 (x)
12 LOAD_FAST 1 (x)
15 LIST_APPEND 2
18 JUMP_ABSOLUTE 6
>> 21 RETURN_VALUE
Usar uma compreensão de lista no lugar de um loop que não cria uma lista, acumular absurdamente uma lista de valores sem sentido e depois jogá-la fora, geralmente é mais lento devido à sobrecarga de criar e estender a lista. A compreensão de lista não é mágica que é inerentemente mais rápida que um bom e antigo loop.
Quanto às funções funcionais de processamento de lista: Embora sejam escritas em C e provavelmente superem as funções equivalentes escritas em Python, elas não são necessariamente a opção mais rápida. É esperada alguma aceleração se a função também estiver escrita em C. Porém, na maioria dos casos, o uso de uma lambda
(ou outra função Python), a sobrecarga da configuração repetida de quadros de pilha Python etc. consome qualquer economia. Simplesmente fazer o mesmo trabalho em linha, sem chamadas de função (por exemplo, uma compreensão da lista em vez de map
ou filter
) geralmente é um pouco mais rápido.
Suponha que em um jogo que estou desenvolvendo, preciso desenhar mapas complexos e enormes usando loops. Essa pergunta seria definitivamente relevante, pois se uma compreensão de lista, por exemplo, for realmente mais rápida, seria uma opção muito melhor para evitar atrasos (apesar da complexidade visual do código).
Provavelmente, se um código como esse já não for rápido o suficiente quando escrito em bom Python não "otimizado", nenhuma micro otimização no nível do Python o tornará rápido o suficiente e você deve começar a pensar em mudar para C. Embora extenso Quando as micro otimizações costumam acelerar consideravelmente o código Python, existe um limite baixo (em termos absolutos) para isso. Além disso, mesmo antes de atingir esse limite, torna-se simplesmente mais econômico (15% de aceleração vs. 300% de aceleração com o mesmo esforço) morder a bala e escrever um pouco de C.
Você pergunta especificamente sobre
map()
,filter()
ereduce()
, mas presumo que você queira saber sobre programação funcional em geral. Tendo testado isso sozinho no problema de calcular distâncias entre todos os pontos dentro de um conjunto de pontos, a programação funcional (usando astarmap
função doitertools
módulo embutido ) mostrou-se um pouco mais lenta que a dos loops for-loops (demorando 1,25 vezes mais, em facto). Aqui está o código de exemplo que eu usei:A versão funcional é mais rápida que a versão processual?
fonte
Escrevi um script simples que testa a velocidade e foi isso que descobri. Na verdade, o loop foi o mais rápido no meu caso. Isso realmente me surpreendeu, confira abaixo (estava calculando a soma dos quadrados).
fonte
int
insquare_sum4
também o torna um pouco mais rápido e um pouco mais lento que o loop for.I modificado @ código de Alisa e usado
cProfile
para mostrar porque compreensão da lista é mais rápido:Aqui estão os resultados:
NA MINHA HUMILDE OPINIÃO:
reduce
emap
são geralmente bem lentos. Além disso, o usosum
nos iteradores quemap
retornaram é lento, comparadosum
a uma listafor_loop
usa append, o que obviamente é lento até certo pontosum
muito mais rápido, em contraste commap
fonte
Adicionando um toque à resposta Alphii , na verdade o loop for seria o segundo melhor e cerca de 6 vezes mais lento que o
map
As principais mudanças foram eliminar as
sum
chamadas lentas e as provavelmente desnecessáriasint()
no último caso. Colocar o loop e o mapa for nos mesmos termos torna isso realmente verdade. Lembre-se de que lambdas são conceitos funcionais e, teoricamente, não devem ter efeitos colaterais, mas, bem, eles podem ter efeitos colaterais como adicionar aa
. Resultados neste caso com Python 3.6.1, Ubuntu 14.04, CPU Intel (R) Core (TM) i7-4770 a 3.40GHzfonte
Consegui modificar alguns códigos do @ alpiii e descobri que a compreensão da lista é um pouco mais rápida do que o loop for. Pode ser causado por
int()
, não é justo entre a compreensão da lista e o loop for.fonte