Itertoolsów na Micropythonie to się nie spodziewałem ;).
Micropython-lib to wielka mała rzecz.
Bardzo mi odpowiada ewolucja Django od czasu kiedy ostatni raz coś w nim robiłem, a było to kilka lat temu. Krótko mówiąc, nadal mam wrażenie jakby to były spodnie szyte na miarę lub śrubokręt, który idealnie leży w łapie i odkręci każdą śrubkę ;). Nie mam uczucia ewolucyjnego zagubienia. To tylko dobrze świadczy o projekcie, bo to co było kiedyś, nie zostało w ciągu tych kilku lat przepisane, najlepiej od zera. Mogło się tak stać tylko dlatego, że już na etapie 1.0-1.4, kiedy poznawałem ten framework, wszystko było zrobione jak należy.
Dziś trafiłem na prezentację o Django Migrations wygłoszoną podczas tegorocznego Pycon. Piękna sprawa:
Ipython Notebook z Mingw-w64-gcc/MSYS2 działa ładnie pod Windows.
Zeromq, jinja2 i sqlite są w repo MSYS2 więc można je zainstalować pacmanem. pyzmq, tornado i pysegments instaluje się przez pip, który jest w paczce mingw-w64-i686-python3-pip.
Super sprawa do testów Cythona i Pythona. W oficjalnym Pythonie nie udało mi się zmusić mingw-w64-gcc do kompilowania Cythona, choć wszystkie zależności notepada instalują się ładnie z pip.
Moich tendencyjnych eksperymentów ciąg dalszy. Zrezygnowałem z Numpy i jestem pod wrażeniem memoryviews w Cythonie. Poniższe to tak na prawdę test wydajności adresowania tablic jednowymiarowych.
Python:
import sys import random def fib(n): a, b = 0, 1 for i in range(n): a, b = b, a + b return a def showfib(n): r = [] for i in range(n): t = fib(random.randint(0,49)) r.append(t) print(t, end=" ") print() if __name__ == '__main__': n=int(sys.argv[1]) showfib(n)
Cython:
#cython: language_level=3, boundscheck=False import sys from libc.stdio cimport printf from libc.stdlib cimport rand, srand from cython.view cimport array from time import time cdef unsigned int fib(int m) nogil: cdef unsigned int a, b, i a, b = 0, 1 for i in range(m): a, b = b, a + b return a cdef showfib(n): cdef r = array(shape=(n,), itemsize=sizeof(unsigned int), format="I") cdef unsigned int [:] rv = r cdef int i cdef unsigned int t for i in range(n): t = fib(rand()%49) rv[i] = t printf("%u ", t) printf("\n") if __name__ == '__main__': n=int(sys.argv[1]) srand(int(time())) showfib(n)
Python-3.4.2:
$ time python fib.py 300000 > /dev/null
real 0m7.564s
user 0m7.543s
sys 0m0.013s
PyPy3-2.4 (portable):
$ time pypy fib.py 300000 > /dev/null
real 0m1.838s
user 0m1.813s
sys 0m0.020s
Cython-0.21.1:
$ time ./fib 300000 > /dev/null
real 0m0.189s
user 0m0.190s
sys 0m0.000s
Cython vs Python: 40,02 x szybciej.
Pypy vs Python: 4,11 x szybciej.
Cython vs PyPy: 9,72 x szybciej.
Idąc jak po nitce do kłębka, w końcu trafiłem na Msys2, czyli minimalny zestaw narzędzi systemowych, oparty o narzędzia uniksowe (głównie GNU) dla Windows.
Co się najbardziej rzuca w oczy w tym zrzucie? 🙂 Ano pacman. Tak, ten sam pacman co w Arch Linuksie, którego używam na co dzień. Co za tym idzie? Wszystkie pakiety (kompilator, biblioteki, python, narzędzia) i kompletne środowisko GNU, są w repo projektu, więc aktualizacja (pod Windows!) to standardowe: pacman -Suy, a przebudowanie pakietu wg własnego uznania to edycja prostych, jak konstrukcja przysłowiowego cepa plików PKGBUILD.
Dla mnie Msys2 to brakujący element systemów Windowsowych.
Dawno nie miałem takiej motywacji do programowania. Cztery dni poszukiwań, grzebania w strzępkach dokumentacji i przykładach. W końcu się udało. Ale od początku. Postanowiłem trochę odświeżyć wiadomości o Pythonie i natrafiłem na Cythona, który mnie zafascynował, ale miałem problem z kodowaniem argumentów programów (sys.argv) do obiektów unikodowych pod Windows (argv w Windows jest w UTF-16, wchar_t **). W żaden sposób nie dało się ich dekodować do Unicode, a binarki dla Linuksa działały bez problemu. Pal licho argv ale to samo dotyczyło kodowania nazw plików. Przetestowałem kilkadziesiąt funkcji C-API Pythona i nic. Skonwertowanie windowsowych szerokich argumentow (wchar_t **) argv z UTF-16 do UTF-8 wydawało się niemożliwe. Aż w jakimś archiwum ircowym trafiłem na wzmiankę, że bez flagi -municode mingw-gcc nie obsługuje pod Windows poprawnie kodowania linii cmd.
Co ciekawe, od początku wydawało mi się celowe generowanie entrypoint-a przez Cythona dla Windows jako:
int wmain(int argc, wchar_t **argv)
Okazuje się, że po dodaniu -municode do gcc mingw-w64 jako entrypoint traktuje właśnie wmain() i używa odpowiednich wersji funkcji z obsługą unicode. Niestety w mingw-gcc 4.8.1 nie ma opcji -municode i wiele osób pewnie z tego powodu ma problemy. W gcc-4.8.1 z mingw-w64 działa jak należy, jest nawet o tym informacja na stronie projektu:
http://sourceforge.net/p/mingw-w64/wiki2/Unicode%20apps/
Szkoda, że wcześniej tego nie znalazłem ;(.
Przykładowa konwersja i kompilacja wygląda tak, w Windows w MSYS:
/c/Python34/Scripts/cython.exe -3 --embed aconv.py gcc aconv.c -I /c/mingw/python/include/python3.4m -L /c/mingw/python/lib/ -lpyth on3.4m -municode -o aconv
Podsumowując. Bardzo mnie to cieszy. W Cythonie, poza niemal pełną zgodnością z Pythonem można includować nagłówki z bibliotek w C i bezpośrednio z nich korzystać w modułach pythonowych, z całą dobrocią typów C a pozwala na przyspieszenie kluczowych fragmentów kodu i kompilację nawet całych programów skonwertowanych do C. A w składni wygląda to jak Python.
Pełen respect dla twórców Cythona.