Python, CPython, Pythonico e Cython: Lógica, termos e desempenho
1. A lógica do Python e seus termos:
Python, CPython, Pythonico, Cython
Pythonico é estar obstinado na construção aprimorada de
sistemas informáticos tendo como base uma guia de estilos. Essa
guia de estilo chama-se PEP-81
. Pythonico é um termo derivado
de Python2
, ou seja, a descrição de uma linguagem de
programação de auto nível, multi uso3
para: web, desktops,
servers e dispositivos embarcados; interpretada e com a
possibilidade de gerar arquivos compilados, criada por Guido Van
Rossum. CPython4
é a implementação original do Python. É a
implementação que você baixa do www.python.org. Trata-se de
uma linguagem com forte filosofia onde o desenvolvimento ágil,
a rápida leitura e a interpretação do código pelos seres humanos
são fatores fundamentais em comparação a outras linguagens de
programação. Além de uma grande capacidade de interagir
facilmente com C/C++
Veja alguns exemplos nos códigos Python abaixo (esses
códigos executam a mesma coisa com desempenho diferente).
Ruim: Bom(LBYL): Aindamelhor(EAFP):
if plano == True: if plano: try:
executar_plano() executar_plano() executar_plano()
Abaixo outro códigoruim except:
if plano != None: ...
executar_plano() finally:
Você percebeu como é fácil ler o código do bloco do meio e
o bloco à direita? O quão rápido a CPU irá executar o código
1
https://www.python.org/dev/peps/pep-0008/
2
http://www.python.org
3
http://spectrum.ieee.org/computing/software/the-2016-top-programming-languages
4
http://stackoverflow.com/questions/17130975/python-vs-cpython
2. assim estruturado com milhares de instruções em construção
aprimorada?
“Deve haver uma - e preferivelmente apenas uma -
maneira óbvia de fazer algo”5
.
A partir deste ponto o conhecimento em tecnologia de
software se faz necessário o que torna a leitura um tanto densa e
difícil. O bloco da direita acima é conhecido como: EAFP (It's
easier to ask forgiveness than permission). O bloco do meio é
conhecido como: LBYL (Look before you leap). Dessa forma, o
EAFP remete a "é mais fácil pedir perdão do que permissão". Isso
significa que em termos de desempenho dos sistemas
informáticos é preferível capturar exceções a testar atributos
com if antes de usá-los. Nos blocos lógicos acima não tem
chaves, parênteses, colchetes, ponto, ponto e vírgula, fecha if,
etc. É só isso, a endentação, ou seja, o recuo do texto em relação
a sua margem instrui o processamento. O except precisa do try e
o try não tem a pretensão de substituir o if.
O comando with, seguindo a filosofia agile, irá fechar
automaticamente o arquivo aberto, mesmo que uma exceção
ocorra dentro do bloco lógico (este é um exemplo prático do que
é a filosofia agile aplicado à programação de software).
Ruim: Muito Bom:
f = open('file.txt' encoding=”utf-8”) with open('file.txt', ‘r’ encoding=”utf-8”) as f:
a = f.read() for linein f:
print(a) print(line)
f.close()
5
https://www.python.org/dev/peps/pep-0020/
3. O extrato de código CPython abaixo lê um arquivo em
formato texto localizado no filesystem, obtendo os 10 primeiros
bytes que se refere a um nome, sendo posteriormente gerado
um arquivo com os nomes ordenados e distintos, ou seja, únicos.
exist = set()
with open(filename, 'r'encoding=”utf-8”) as r:
with open(filename + '.out', 'w', encoding=”utf-8”) as w:
for line in sorted(r):
nome = line[0:10].strip()
if nome not in exist:
if nome != 'UID':
w.write(nome)
w.write('n')
exist.add(nome)
Neste extrato de código o resultado do arquivo gera é exibido
em tela.
with open(filename + '.out', 'r', encoding=”utf-8”) as r:
for line in r:
print (line, end="")
4. Alto desempenho com Cython
"Cython é o elo perdido entre a simplicidade do Python e a
velocidade do C/C++" Stefan Behnel. Fato que se traduz em um
cenário ganha-ganha.
Cython é uma ferramenta para:
Converter código Python para código C
Acelerar os módulos Python existentes, não reescreva!
Chamar códigos C a partir do Python
O Cython faz algumas conversões que utilizam menor
quantidade de chamadas ao interpretador Python. Dessa forma,
o ganho em desempenho é alcançado.
Veja os exemplos abaixo rodando para o seguinte código:
#!/usr/bin/env python3
# coding=utf-8
import time
start_time = time.time()
for i in range(999999999):
pass
print ('Início={0}, Fim={1}, Tempo={2}s segundos'.format(start_time, time.time(),
time.time() - start_time))
5. Ubuntu Desktop v. 16.04 32bits com gcc v. 5.4.0 (Dual core 1.66Ghz):
Python v. 3.5.2 Cython v. 0.266
for i in range(999999999) for (i=0; i<999999999; i++)
166.75153851509094 μs 139.28135538101196 μs
Python v. 2.7.12 Cython v. 0.267
for i in range(999999999) for (i=0; i<999999999; i++)
Memory Error Memory Error
*************
Ubuntu Server v. 17.04 (GNU/Linux 4.10.0-32-generic x86_64) com gcc v. 6.3.0
(Micro instance, 1vCPU, 0,6GB Memory):
Python v. 3.5.3 Cython v. 0.268
for i in range(999999999) for (i=0; i<999999999; i++)
104.71606087684631 μs 60.71505284309387 μs
Python v. 2.7.13 Cython v. 0.269
for i in range(999999999) for (i=0; i<999999999; i++)
Memory Error Memory Error
6
CompiladobaseadoemPython-3(sintaxee semânticade códigos)
7
CompialdobaseadoemPython-2(sintaxee semânticade códigos)
8
CompiladobaseadoemPython-3(sintaxee semânticade códigos)
9
CompialdobaseadoemPython-2(sintaxee semânticade códigos)
6. Cython na pratica
$ cat olamundo.py
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
print ("Olá mundo")
$ python3 olamundo.py
Olá mundo
$ cython --embed olamundo.py -3
$ gcc -Os -I /usr/include/python3.5m -o olamundo olamundo.c -
lpython3.5m -lpthread -lm -lutil -ldl
$ ls -la olamundo*
-rwxrwxr-x. 1 marcos marcos 18368jan 18 20:14 olamundo
-rw-rw-r--. 1 marcos marcos 78047jan 18 20:13 olamundo.c
-rw-rw-r--. 1 marcos marcos 68 jan 18 20:10 olamundo.py
$ ./olamundo
Olá mundo
Perceba o tamanho dos arquivos. É possível executar um
arquivo Python com 68 bytes. Diferentemente de um arquivo
executável que possui 18368 bytes. Esse fato não significa que
um é melhor e o outro pior, mas responder a seguinte questão:
Qual opção é a mais indicada às características do meu projeto?
7. Qual o objetivo?
Escrever código eficiente em Python, aproveitando as suas
características otimizadas, bem como baseado na guia de estilos
da PEP-8 (Pythonico) e quando for necessário forte desempenho,
utilizar o Cython como uma das opções disponíveis, entre outras,
usadas separadas ou em conjunto.
O Python é mais lento quando comparado com C/C++.
Entretanto, o Python faz um bom trabalho quando comparado
com outras linguagens da sua categoria, como: Java, JavaScript,
Perl, Tcl, ou Smalltalk.
O core de desenvolvimento do Python é muito poderoso e
atuante e a linguagem está evoluindo fortemente, rotinas que
aproveitam os modernos processadores com vários núcleos de
processamento estão disponibilizadas na linguagem com forte
inovação, versão após versão do software. Nos últimos anos um
trabalho incrivel está sendo feito.
8. Fontes:
Effective Python 59 specific ways to write better Python by
Brett Slatkin
Python Cookbook Third Edition by David Beazley and Brian K.
Jones
The Hitchhiker’s Guide to Python by Kenneth Reitz
PEP 8 - Style Guide for Python Code -
https://www.python.org/dev/peps/pep-0008/
PEP 20 - The Zen of Python -
https://www.python.org/dev/peps/pep-0020/
Making Python run faster: a case study
http://faingezicht.com/articles/2016/12/25/means/
Comparing Python to Other Languages
https://www.python.org/doc/essays/comparisons/
Using the Cython Compiler to write fast Python code
http://www.behnel.de/cython200910/talk.html
Why is Python so popular despite being so slow?
https://www.quora.com/Why-is-Python-so-popular-despite-
being-so-slow
9. What are differences between multithreading, multiprocessing
and asyncio in Python?
https://www.quora.com/What-are-differences-between-
multithreading-multiprocessing-and-asyncio-in-Python
5 Reasons why Python is Powerful Enough for Google
https://www.codefellows.org/blog/5-reasons-why-python-is-
powerful-enough-for-google/
Marcos Aurelio Barranco
Escrito em: 21/01/2017
Atualizado em: 31/01/2018