Cyfroteka.pl

klikaj i czytaj online

Cyfro
Czytomierz
00456 007408 13615080 na godz. na dobę w sumie
Python. Programuj szybko i wydajnie - ebook/pdf
Python. Programuj szybko i wydajnie - ebook/pdf
Autor: , Liczba stron: 351
Wydawca: Helion Język publikacji: polski
ISBN: 978-83-283-0469-7 Data wydania:
Lektor:
Kategoria: ebooki >> komputery i informatyka >> programowanie >> python - programowanie
Porównaj ceny (książka, ebook, audiobook).

Wydajne aplikacje w języku Python!

Python to skryptowy język programowania istniejący na rynku od wielu lat — jego pierwsza wersja pojawiła się w 1991 roku. Przejrzystość kodu źródłowego była jednym z głównych celów Guida van Rossuma, twórcy tego języka. Dziś Python cieszy się dużą popularnością, co z jednej strony świadczy o jego przydatności, a z drugiej gwarantuje użytkownikom szerokie wsparcie społeczności programistów języka. Python jest elastyczny, dopuszcza różne style programowania, a dzięki temu znajduje zastosowanie w wielu miejscach świata IT.

Jeżeli chcesz w pełni wykorzystać możliwości Pythona i tworzyć wydajne rozwiązania, to koniecznie zaopatrz się w tę książkę! Dzięki niej dowiesz się, jak wykorzystać profilowanie do lokalizowania „wąskich gardeł”, oraz poznasz efektywne techniki wyszukiwania danych na listach, w słownikach i zbiorach. Ponadto zdobędziesz wiedzę na temat obliczeń macierzowych i wektorowych oraz zobaczysz, jak kompilacja do postaci kodu C wpływa na wydajność Twojego rozwiązania. Osobne rozdziały zostały poświęcone współbieżności oraz modułowi multiprocessing. Opanowanie tych zagadnień pozwoli Ci ogromnie przyspieszyć działanie Twojej aplikacji. Na sam koniec nauczysz się tworzyć klastry i kolejki zadań oraz optymalizować zużycie pamięci RAM. Rozdział dwunasty to gratka dla wszystkich — zawiera najlepsze porady specjalistów z branży! Książka ta jest obowiązkową lekturą dla wszystkich programistów chcących tworzyć wydajne rozwiązania w języku Python.
 

Wyciśnij z Pythona siódme poty!

Znajdź podobne książki Ostatnio czytane w tej kategorii

Darmowy fragment publikacji:

Tytuł oryginału: High Performance Python: Practical Performant Programming for Humans Tłumaczenie: Piotr Pilch ISBN: 978-83-283-0466-6 © 2015 Helion S.A. Authorized Polish translation of the English edition of High Performance Python, ISBN 9781449361594 © 2014 Micha Gorelick and Ian Ozsvald. This translation is published and sold by permission of O’Reilly Media, Inc., which owns or controls all rights to publish and sell the same. All rights reserved. No part of this book may be reproduced or transmitted in any form or by any means, electronic or mechanical, including photocopying, recording or by any information storage retrieval system, without permission from the Publisher. Wszelkie prawa zastrzeżone. Nieautoryzowane rozpowszechnianie całości lub fragmentu niniejszej publikacji w jakiejkolwiek postaci jest zabronione. Wykonywanie kopii metodą kserograficzną, fotograficzną, a także kopiowanie książki na nośniku filmowym, magnetycznym lub innym powoduje naruszenie praw autorskich niniejszej publikacji. Wszystkie znaki występujące w tekście są zastrzeżonymi znakami firmowymi bądź towarowymi ich właścicieli. Autor oraz Wydawnictwo HELION dołożyli wszelkich starań, by zawarte w tej książce informacje były kompletne i rzetelne. Nie biorą jednak żadnej odpowiedzialności ani za ich wykorzystanie, ani za związane z tym ewentualne naruszenie praw patentowych lub autorskich. Autor oraz Wydawnictwo HELION nie ponoszą również żadnej odpowiedzialności za ewentualne szkody wynikłe z wykorzystania informacji zawartych w książce. Wydawnictwo HELION ul. Kościuszki 1c, 44-100 GLIWICE tel. 32 231 22 19, 32 230 98 63 e-mail: helion@helion.pl WWW: http://helion.pl (księgarnia internetowa, katalog książek) Drogi Czytelniku! Jeżeli chcesz ocenić tę książkę, zajrzyj pod adres http://helion.pl/user/opinie/pytpsw Możesz tam wpisać swoje uwagi, spostrzeżenia, recenzję. Printed in Poland. • Kup książkę • Poleć książkę • Oceń książkę • Księgarnia internetowa • Lubię to! » Nasza społeczność Spis tre(cid:316)ci Przedmowa ....................................................................................................................9 1. Wydajny kod Python ................................................................................................... 15 Podstawowy system komputerowy ................................................................................................ 15 Jednostki obliczeniowe ................................................................................................................16 Jednostki pami(cid:246)ci .........................................................................................................................19 Warstwy komunikacji ..................................................................................................................21 (cid:227)(cid:241)czenie ze sob(cid:241) podstawowych elementów ................................................................................ 22 Porównanie wyidealizowanego przetwarzania z maszyn(cid:241) wirtualn(cid:241) j(cid:246)zyka Python ............23 Dlaczego warto u(cid:276)ywa(cid:232) j(cid:246)zyka Python? ........................................................................................ 26 2. U(cid:348)ycie profilowania do znajdowania w(cid:233)skich garde(cid:293) ...............................................29 Efektywne profilowanie .................................................................................................................... 30 Wprowadzenie do zbioru Julii ......................................................................................................... 31 Obliczanie pe(cid:228)nego zbioru Julii ........................................................................................................ 34 Proste metody pomiaru czasu — instrukcja print i dekorator ................................................... 37 Prosty pomiar czasu za pomoc(cid:241) polecenia time systemu Unix ................................................. 40 U(cid:276)ycie modu(cid:228)u cProfile ..................................................................................................................... 41 U(cid:276)ycie narz(cid:246)dzia runsnake do wizualizacji danych wyj(cid:264)ciowych modu(cid:228)u cProfile ............. 46 U(cid:276)ycie narz(cid:246)dzia line_profiler do pomiarów dotycz(cid:241)cych kolejnych wierszy kodu ............ 46 U(cid:276)ycie narz(cid:246)dzia memory_profiler do diagnozowania wykorzystania pami(cid:246)ci ................... 51 Inspekcja obiektów w stercie za pomoc(cid:241) narz(cid:246)dzia heapy ........................................................ 56 U(cid:276)ycie narz(cid:246)dzia dowser do generowania aktywnego wykresu dla zmiennych z utworzonymi instancjami ................................................................................ 58 U(cid:276)ycie modu(cid:228)u dis do sprawdzania kodu bajtowego narz(cid:246)dzia CPython ............................. 60 Ró(cid:276)ne metody, ró(cid:276)na z(cid:228)o(cid:276)ono(cid:264)(cid:232) ................................................................................................62 Testowanie jednostkowe podczas optymalizacji w celu zachowania poprawno(cid:264)ci .............. 64 Dekorator @profile bez operacji ................................................................................................64 Strategie udanego profilowania kodu ............................................................................................ 66 Podsumowanie .................................................................................................................................... 67 3 Kup książkęPoleć książkę 3. Listy i krotki ..................................................................................................................69 Bardziej efektywne wyszukiwanie .................................................................................................. 71 Porównanie list i krotek .................................................................................................................... 73 Listy jako tablice dynamiczne .......................................................................................................... 74 Krotki w roli tablic statycznych ....................................................................................................... 77 Podsumowanie .................................................................................................................................... 78 4. S(cid:293)owniki i zbiory ..........................................................................................................79 Jak dzia(cid:228)aj(cid:241) s(cid:228)owniki i zbiory? .......................................................................................................... 82 Wstawianie i pobieranie ..............................................................................................................82 Usuwanie .......................................................................................................................................85 Zmiana wielko(cid:264)ci .........................................................................................................................85 Funkcje mieszania i entropia ......................................................................................................86 S(cid:228)owniki i przestrzenie nazw ........................................................................................................... 89 Podsumowanie .................................................................................................................................... 92 5. Iteratory i generatory ..................................................................................................93 Iteratory dla szeregów niesko(cid:254)czonych ......................................................................................... 96 Warto(cid:264)ciowanie leniwe generatora ................................................................................................. 97 Podsumowanie .................................................................................................................................. 101 6. Obliczenia macierzowe i wektorowe ....................................................................... 103 Wprowadzenie do problemu ......................................................................................................... 104 Czy listy j(cid:246)zyka Python s(cid:241) wystarczaj(cid:241)co dobre? ....................................................................... 107 Problemy z przesadn(cid:241) alokacj(cid:241) ...............................................................................................109 Fragmentacja pami(cid:246)ci ...................................................................................................................... 111 Narz(cid:246)dzie perf ............................................................................................................................113 Podejmowanie decyzji z wykorzystaniem danych wyj(cid:264)ciowych narz(cid:246)dzia perf ..........115 Wprowadzenie do narz(cid:246)dzia numpy .....................................................................................116 Zastosowanie narz(cid:246)dzia numpy w przypadku problemu dotycz(cid:241)cego dyfuzji .................. 119 Przydzia(cid:228)y pami(cid:246)ci i operacje wewn(cid:246)trzne ...........................................................................121 Optymalizacje selektywne: znajdowanie tego, co wymaga poprawienia .......................124 Modu(cid:228) numexpr: przyspieszanie i upraszczanie operacji wewn(cid:246)trznych ............................. 127 Przestroga: weryfikowanie „optymalizacji” (biblioteka scipy) ................................................ 129 Podsumowanie .................................................................................................................................. 131 7. Kompilowanie do postaci kodu C .............................................................................. 133 Jakie wzrosty szybko(cid:264)ci s(cid:241) mo(cid:276)liwe? ........................................................................................... 134 Porównanie kompilatorów JIT i AOT ........................................................................................... 136 Dlaczego informacje o typie u(cid:228)atwiaj(cid:241) przyspieszenie dzia(cid:228)ania kodu? ................................ 136 U(cid:276)ycie kompilatora kodu C ............................................................................................................ 137 Analiza przyk(cid:228)adu zbioru Julii ....................................................................................................... 138 Cython ................................................................................................................................................ 139 Kompilowanie czystego kodu Python za pomoc(cid:241) narz(cid:246)dzia Cython ..............................139 U(cid:276)ycie adnotacji kompilatora Cython do analizowania bloku kodu ...............................141 Dodawanie adnotacji typu .......................................................................................................143 4 (cid:95) Spis tre(cid:316)ci Kup książkęPoleć książkę Shed Skin ............................................................................................................................................ 147 Tworzenie modu(cid:228)u rozszerzenia .............................................................................................148 Koszt zwi(cid:241)zany z kopiami pami(cid:246)ci ........................................................................................150 Cython i numpy ................................................................................................................................ 151 Przetwarzanie równoleg(cid:228)e rozwi(cid:241)zania na jednym komputerze z wykorzystaniem interfejsu OpenMP ................................................................................152 Numba ................................................................................................................................................ 154 Pythran ............................................................................................................................................... 155 PyPy .................................................................................................................................................... 157 Ró(cid:276)nice zwi(cid:241)zane z czyszczeniem pami(cid:246)ci ...........................................................................158 Uruchamianie interpretera PyPy i instalowanie modu(cid:228)ów ................................................159 Kiedy stosowa(cid:232) poszczególne technologie? ................................................................................ 160 Inne przysz(cid:228)e projekty ...............................................................................................................162 Uwaga dotycz(cid:241)ca uk(cid:228)adów GPU ............................................................................................162 Oczekiwania dotycz(cid:241)ce przysz(cid:228)ego projektu kompilatora .................................................163 Interfejsy funkcji zewn(cid:246)trznych ..................................................................................................... 163 ctypes ............................................................................................................................................164 cffi ..................................................................................................................................................166 f2py ...............................................................................................................................................169 Modu(cid:228) narz(cid:246)dzia CPython .......................................................................................................171 Podsumowanie .................................................................................................................................. 174 8. Wspó(cid:293)bie(cid:348)no(cid:316)(cid:235) ............................................................................................................175 Wprowadzenie do programowania asynchronicznego ............................................................. 176 Przeszukiwacz szeregowy .............................................................................................................. 179 gevent .................................................................................................................................................. 181 tornado ............................................................................................................................................... 185 AsyncIO .............................................................................................................................................. 188 Przyk(cid:228)ad z baz(cid:241) danych .................................................................................................................. 190 Podsumowanie .................................................................................................................................. 193 9. Modu(cid:293) multiprocessing .............................................................................................. 195 Modu(cid:228) multiprocessing ................................................................................................................... 198 Przybli(cid:276)enie liczby pi przy u(cid:276)yciu metody Monte Carlo ......................................................... 200 Przybli(cid:276)anie liczby pi za pomoc(cid:241) procesów i w(cid:241)tków .............................................................. 201 Zastosowanie obiektów j(cid:246)zyka Python ..................................................................................201 Liczby losowe w systemach przetwarzania równoleg(cid:228)ego ................................................208 Zastosowanie narz(cid:246)dzia numpy .............................................................................................209 Znajdowanie liczb pierwszych ....................................................................................................... 211 Kolejki zada(cid:254) roboczych ...........................................................................................................217 Weryfikowanie liczb pierwszych za pomoc(cid:241) komunikacji mi(cid:246)dzyprocesowej .................... 221 Rozwi(cid:241)zanie z przetwarzaniem szeregowym ......................................................................225 Rozwi(cid:241)zanie z prostym obiektem Pool ..................................................................................225 Rozwi(cid:241)zanie z bardzo prostym obiektem Pool dla mniejszych liczb ..............................227 U(cid:276)ycie obiektu Manager.Value jako flagi ..............................................................................228 Spis tre(cid:316)ci (cid:95) 5 Kup książkęPoleć książkę U(cid:276)ycie systemu Redis jako flagi ..............................................................................................229 U(cid:276)ycie obiektu RawValue jako flagi .......................................................................................232 U(cid:276)ycie modu(cid:228)u mmap jako flagi .............................................................................................232 U(cid:276)ycie modu(cid:228)u mmap do odtworzenia flagi ........................................................................233 Wspó(cid:228)u(cid:276)ytkowanie danych narz(cid:246)dzia numpy za pomoc(cid:241) modu(cid:228)u multiprocessing ......... 236 Synchronizowanie dost(cid:246)pu do zmiennych i plików .................................................................. 242 Blokowanie plików ....................................................................................................................242 Blokowanie obiektu Value ........................................................................................................245 Podsumowanie .................................................................................................................................. 248 10. Klastry i kolejki zada(cid:295) ...............................................................................................249 Zalety klastrowania .......................................................................................................................... 250 Wady klastrowania .......................................................................................................................... 251 Strata o warto(cid:264)ci 462 milionów dolarów na gie(cid:228)dzie Wall Street z powodu kiepskiej strategii aktualizacji klastra ...............................................................252 24-godzinny przestój us(cid:228)ugi Skype w skali globalnej .........................................................253 Typowe projekty klastrowe ............................................................................................................ 254 Metoda rozpocz(cid:246)cia tworzenia rozwi(cid:241)zania klastrowego ........................................................ 254 Sposoby na unikni(cid:246)cie k(cid:228)opotów podczas korzystania z klastrów ......................................... 255 Trzy rozwi(cid:241)zania klastrowe ........................................................................................................... 257 U(cid:276)ycie modu(cid:228)u Parallel Python dla prostych klastrów lokalnych ...................................257 U(cid:276)ycie modu(cid:228)u IPython Parallel do obs(cid:228)ugi bada(cid:254) .............................................................259 U(cid:276)ycie systemu NSQ dla niezawodnych klastrów produkcyjnych ........................................ 262 Kolejki ...........................................................................................................................................263 Publikator/subskrybent ............................................................................................................264 Rozproszone obliczenia liczb pierwszych .............................................................................266 Inne warte uwagi narz(cid:246)dzia klastrowania ................................................................................... 268 Podsumowanie .................................................................................................................................. 269 11. Mniejsze wykorzystanie pami(cid:253)ci RAM .....................................................................271 Obiekty typów podstawowych s(cid:241) kosztowne ............................................................................ 272 Modu(cid:228) array zu(cid:276)ywa mniej pami(cid:246)ci do przechowywania wielu obiektów typu podstawowego ................................................................................................................273 Analiza wykorzystania pami(cid:246)ci RAM w kolekcji ...................................................................... 276 Bajty i obiekty Unicode .................................................................................................................... 277 Efektywne przechowywanie zbiorów tekstowych w pami(cid:246)ci RAM ...................................... 279 Zastosowanie metod dla 8 milionów tokenów .....................................................................280 Wskazówki dotycz(cid:241)ce mniejszego wykorzystania pami(cid:246)ci RAM .......................................... 288 Probabilistyczne struktury danych ............................................................................................... 289 Obliczenia o bardzo du(cid:276)ym stopniu przybli(cid:276)enia z wykorzystaniem jednobajtowego licznika Morrisa .......................................................................................................................290 Warto(cid:264)ci k-minimum .................................................................................................................291 Filtry Blooma ...............................................................................................................................295 Licznik LogLog ...........................................................................................................................299 Praktyczny przyk(cid:228)ad ..................................................................................................................303 6 (cid:95) Spis tre(cid:316)ci Kup książkęPoleć książkę 12. Rady specjalistów z bran(cid:348)y .......................................................................................307 Narz(cid:246)dzie Social Media Analytics (SoMA) firmy Adaptive Lab ............................................. 307 J(cid:246)zyk Python w firmie Adaptive Lab .....................................................................................308 Projekt narz(cid:246)dzia SoMA ...........................................................................................................308 Zastosowana metodologia projektowa ..................................................................................309 Serwisowanie systemu SoMA ..................................................................................................309 Rada dla in(cid:276)ynierów z bran(cid:276)y .................................................................................................310 Technika g(cid:228)(cid:246)bokiego uczenia prezentowana przez firm(cid:246) RadimRehurek.com .................... 310 Strza(cid:228) w dziesi(cid:241)tk(cid:246) .....................................................................................................................311 Rady dotycz(cid:241)ce optymalizacji ..................................................................................................313 Podsumowanie ...........................................................................................................................315 Uczenie maszynowe o du(cid:276)ej skali gotowe do zastosowa(cid:254) produkcyjnych w firmie Lyst.com .................................................................. 315 Rola j(cid:246)zyka Python w witrynie Lyst .......................................................................................316 Projekt klastra .............................................................................................................................316 Ewolucja kodu w szybko rozwijaj(cid:241)cej si(cid:246) nowej firmie ......................................................316 Budowanie mechanizmu rekomendacji .................................................................................316 Raportowanie i monitorowanie ...............................................................................................317 Rada ..............................................................................................................................................317 Analiza serwisu spo(cid:228)eczno(cid:264)ciowego o du(cid:276)ej skali w firmie Smesh ........................................ 318 Rola j(cid:246)zyka Python w firmie Smesh .......................................................................................318 Platforma ......................................................................................................................................318 Dopasowywanie (cid:228)a(cid:254)cuchów w czasie rzeczywistym z du(cid:276)(cid:241) wydajno(cid:264)ci(cid:241) .....................319 Raportowanie, monitorowanie, debugowanie i wdra(cid:276)anie ...............................................320 Interpreter PyPy zapewniaj(cid:241)cy powodzenie systemów przetwarzania danych i systemów internetowych ............................................................................................................ 322 Wymagania wst(cid:246)pne .................................................................................................................322 Baza danych ................................................................................................................................323 Aplikacja internetowa ................................................................................................................323 Mechanizm OCR i t(cid:228)umaczenie ...............................................................................................324 Dystrybucja zada(cid:254) i procesy robocze .....................................................................................324 Podsumowanie ...........................................................................................................................325 Kolejki zada(cid:254) w serwisie internetowym Lanyrd.com ............................................................... 325 Rola j(cid:246)zyka Python w serwisie Lanyrd ..................................................................................325 Zapewnianie odpowiedniej wydajno(cid:264)ci kolejki zada(cid:254) .......................................................326 Raportowanie, monitorowanie, debugowanie i wdra(cid:276)anie ...............................................326 Rada dla programistów z bran(cid:276)y ............................................................................................326 Skorowidz ..................................................................................................................329 Spis tre(cid:316)ci (cid:95) 7 Kup książkęPoleć książkę 8 (cid:95) Spis tre(cid:316)ci Kup książkęPoleć książkę ROZDZIA(cid:292) 7. Kompilowanie do postaci kodu C Pytania, na jakie b(cid:253)dziesz w stanie udzieli(cid:235) odpowiedzi po przeczytaniu rozdzia(cid:293)u (cid:120) Jak mo(cid:276)esz sprawi(cid:232), (cid:276)e kod Python b(cid:246)dzie dzia(cid:228)a(cid:232) jako kod ni(cid:276)szego poziomu? (cid:120) Jaka jest ró(cid:276)nica mi(cid:246)dzy kompilatorem JIT i kompilatorem AOT? (cid:120) Jakie zadania mog(cid:241) by(cid:232) wykonywane przez skompilowany kod Python szybciej ni(cid:276) w przypadku zwyk(cid:228)ego kodu Python? (cid:120) Dlaczego adnotacje typu zwi(cid:246)kszaj(cid:241) szybko(cid:264)(cid:232) skompilowanego kodu Python? (cid:120) Jak mo(cid:276)esz utworzy(cid:232) modu(cid:228)y dla kodu Python za pomoc(cid:241) j(cid:246)zyka C lub Fortran? (cid:120) Jak mo(cid:276)esz u(cid:276)y(cid:232) w kodzie Python bibliotek j(cid:246)zyka C lub Fortran? Najprostszym sposobem przyspieszenia kodu jest ograniczenie liczby operacji, jakie b(cid:246)dzie wykonywa(cid:232). Zak(cid:228)adaj(cid:241)c, (cid:276)e zosta(cid:228)y ju(cid:276) wybrane dobre algorytmy i zmniejszono ilo(cid:264)(cid:232) prze- twarzanych danych, najprostsza metoda, by wykonywa(cid:232) mniejsz(cid:241) liczb(cid:246) instrukcji, polega na skompilowaniu kodu do postaci kodu maszynowego. W tym zakresie j(cid:246)zyk Python oferuje kilka opcji obejmuj(cid:241)cych narz(cid:246)dzia do kompilowania oparte na czystym kodzie C, takie jak Cython, Shed Skin i Pythran, kompilowanie bazuj(cid:241)ce na kompilatorze LLVM za po(cid:264)rednictwem narz(cid:246)dzia Numba oraz zast(cid:246)pcz(cid:241) maszyn(cid:246) wirtu- aln(cid:241) PyPy, która zawiera wbudowany kompilator JIT (Just in Time). Przy podejmowaniu de- cyzji dotycz(cid:241)cej (cid:264)cie(cid:276)ki, jaka zostanie obrana, konieczne jest zrównowa(cid:276)enie wymaga(cid:254) zwi(cid:241)- zanych z (cid:228)atwo(cid:264)ci(cid:241) dostosowania kodu i impetu zespo(cid:228)u. Ka(cid:276)de z wymienionych narz(cid:246)dzi dodaje now(cid:241) zale(cid:276)no(cid:264)(cid:232) do szeregu u(cid:276)ywanych narz(cid:246)dzi. Dodatkowo narz(cid:246)dzie Cython wymaga pisania w j(cid:246)zyku nowego typu (hybrydzie j(cid:246)zyków Python i C), co wi(cid:241)(cid:276)e si(cid:246) z konieczno(cid:264)ci(cid:241) zdobycia nowej umiej(cid:246)tno(cid:264)ci. Wykorzystanie no- wego j(cid:246)zyka narz(cid:246)dzia Cython mo(cid:276)e mie(cid:232) negatywny wp(cid:228)yw na impet zespo(cid:228)u, poniewa(cid:276) jego cz(cid:228)onkowie bez znajomo(cid:264)ci j(cid:246)zyka C mog(cid:241) mie(cid:232) problem z obs(cid:228)ug(cid:241) takiego kodu. Jednak w praktyce jest to raczej niewielki k(cid:228)opot, gdy(cid:276) kod narz(cid:246)dzia Cython b(cid:246)dzie u(cid:276)ywany tylko w dobrze wybranych, niewielkich obszarach kodu. 133 Kup książkęPoleć książkę Godne uwagi jest to, (cid:276)e przeprowadzanie profilowania kodu w odniesieniu do pami(cid:246)ci i proce- sora prawdopodobnie spowoduje, (cid:276)e zaczniesz si(cid:246) zastanawia(cid:232) nad optymalizacjami algoryt- micznymi wy(cid:276)szego poziomu, które mog(cid:241) zosta(cid:232) zastosowane. Takie zmiany algorytmiczne (czyli u(cid:276)ycie dodatkowej logiki w celu unikni(cid:246)cia oblicze(cid:254) lub buforowanie eliminuj(cid:241)ce po- nowne obliczenia) mog(cid:241) pomóc Ci zapobiega(cid:232) wykonywaniu w kodzie zb(cid:246)dnych dzia(cid:228)a(cid:254). Ekspresywno(cid:264)(cid:232) kodu Python u(cid:228)atwia zauwa(cid:276)enie takich mo(cid:276)liwo(cid:264)ci algorytmicznych. W pod- rozdziale „Technika g(cid:228)(cid:246)bokiego uczenia prezentowana przez firm(cid:246) RadimRehurek.com” z roz- dzia(cid:228)u 12. Radim (cid:261)eh(cid:270)(cid:262)ek wyja(cid:264)nia, jak implementacja kodu Python mo(cid:276)e wygra(cid:232) z czyst(cid:241) implementacj(cid:241) stworzon(cid:241) w j(cid:246)zyku C. W rozdziale dokonamy przegl(cid:241)du nast(cid:246)puj(cid:241)cych narz(cid:246)dzi: (cid:120) Cython — jest to najcz(cid:246)(cid:264)ciej u(cid:276)ywane narz(cid:246)dzie do kompilowania do postaci kodu C, które uwzgl(cid:246)dnia zarówno narz(cid:246)dzie numpy, jak i zwyk(cid:228)y kod Python (wymagana jest znajomo(cid:264)(cid:232) j(cid:246)zyka C). (cid:120) Shed Skin — zautomatyzowany konwerter Python-C przeznaczony dla kodu, który nie bazuje na narz(cid:246)dziu numpy. (cid:120) Numba — nowy kompilator stworzony z my(cid:264)l(cid:241) o kodzie bazuj(cid:241)cym na narz(cid:246)dziu numpy. (cid:120) Pythran — nowy kompilator przeznaczony zarówno dla kodu bazuj(cid:241)cego na narz(cid:246)dziu numpy, jak i innego kodu. (cid:120) PyPy — stabilny kompilator JIT dla kodu, który nie bazuje na narz(cid:246)dziu numpy. Kod taki zast(cid:246)puje zwyk(cid:228)y plik wykonywalny Python. W dalszej cz(cid:246)(cid:264)ci rozdzia(cid:228)u przyjrzymy si(cid:246) interfejsom funkcji zewn(cid:246)trznych, które umo(cid:276)liwiaj(cid:241) skompilowanie kodu C do postaci modu(cid:228)ów rozszerze(cid:254) dla j(cid:246)zyka Python. Wbudowany in- terfejs API tego j(cid:246)zyka jest u(cid:276)ywany razem z narz(cid:246)dziami ctypes i cffi (twórców kompilatora PyPy) oraz z konwerterem Fortran-Python f2py. Jakie wzrosty szybko(cid:316)ci s(cid:233) mo(cid:348)liwe? Je(cid:264)li problem zwi(cid:241)zany jest z metod(cid:241) kompilowania, ca(cid:228)kiem prawdopodobne s(cid:241) wzrosty szybko(cid:264)ci wynosz(cid:241)ce rz(cid:241)d wielko(cid:264)ci lub wi(cid:246)cej. Przyjrzymy si(cid:246) tutaj ró(cid:276)nym metodom osi(cid:241)- gania przyspiesze(cid:254) wynosz(cid:241)cych jeden lub dwa rz(cid:246)dy wielko(cid:264)ci dla pojedynczego rdzenia, a tak(cid:276)e w przypadku zastosowania wielu rdzeni za po(cid:264)rednictwem interfejsu OpenMP. Kod Python, który zwykle b(cid:246)dzie dzia(cid:228)a(cid:232) szybciej po skompilowaniu, prawdopodobnie s(cid:228)u(cid:276)y do zastosowa(cid:254) matematycznych, a ponadto zawiera raczej wiele p(cid:246)tli wielokrotnie powtarzaj(cid:241)cych te same operacje. W obr(cid:246)bie tych p(cid:246)tli mo(cid:276)liwe jest tworzenie wielu obiektów tymczasowych. Ma(cid:228)o prawdopodobne jest to, (cid:276)e kod wywo(cid:228)uj(cid:241)cy biblioteki zewn(cid:246)trzne (np. wyra(cid:276)enia regu- larne, operacje na (cid:228)a(cid:254)cuchach, wywo(cid:228)ania bibliotek bazy danych) wyka(cid:276)e jakiekolwiek przy- spieszenie po skompilowaniu. Programy powi(cid:241)zane z operacjami wej(cid:264)cia-wyj(cid:264)cia równie(cid:276) raczej nie pozwol(cid:241) osi(cid:241)gn(cid:241)(cid:232) znacznych przyspiesze(cid:254). Je(cid:264)li kod Python koncentruje si(cid:246) na wywo(cid:228)ywaniu wektoryzowanych funkcji narz(cid:246)dzia numpy, wcale mo(cid:276)e nie dzia(cid:228)a(cid:232) szybciej po skompilowaniu. Inaczej b(cid:246)dzie tylko wtedy, gdy kompilo- wany kod to g(cid:228)ównie kod Python (a ponadto prawdopodobnie w sytuacji, kiedy w kodzie jest wykonywana p(cid:246)tla). W rozdziale 6. omówiono operacje narz(cid:246)dzia numpy. Okazuje si(cid:246), (cid:276)e w ich przypadku kompilowanie nie b(cid:246)dzie pomocne, poniewa(cid:276) nie wyst(cid:246)puje wiele obiektów po(cid:264)rednich. 134 (cid:95) Rozdzia(cid:293) 7. Kompilowanie do postaci kodu C Kup książkęPoleć książkę Ogólnie rzecz bior(cid:241)c, bardzo ma(cid:228)o prawdopodobne jest to, (cid:276)e skompilowany kod b(cid:246)dzie w ogóle szybszy od funkcji napisanej w j(cid:246)zyku C. Niemniej jednak taki kod nie b(cid:246)dzie te(cid:276) dzia(cid:228)a(cid:232) znacznie wolniej. Ca(cid:228)kiem mo(cid:276)liwe jest to, (cid:276)e kod C wygenerowany z kodu Python b(cid:246)dzie dzia(cid:228)a(cid:232) tak samo szybko jak r(cid:246)cznie napisana funkcja C, chyba (cid:276)e programista u(cid:276)y- waj(cid:241)cy j(cid:246)zyka C dysponuje szczególnie du(cid:276)(cid:241) wiedz(cid:241) na temat metod dostrajania kodu C do architektury docelowej platformy sprz(cid:246)towej. W przypadku kodu stworzonego z my(cid:264)l(cid:241) o operacjach matematycznych mo(cid:276)liwe jest, (cid:276)e r(cid:246)cznie stworzona funkcja j(cid:246)zyka Fortran przewy(cid:276)szy odpowiadaj(cid:241)c(cid:241) jej funkcj(cid:246) C. Jednak(cid:276)e i tym razem b(cid:246)dzie to raczej wymaga(cid:232) wiedzy eksperckiej. Generalnie rzecz bior(cid:241)c, wynik kompilacji (uzyskany prawdopodobnie z wykorzystaniem narz(cid:246)dzia Cython, Pythran lub Shed Skin) b(cid:246)dzie zbli(cid:276)ony do wyniku dla r(cid:246)cznie napisanego kodu C w stopniu wymaganym przez wi(cid:246)kszo(cid:264)(cid:232) programistów. Podczas profilowania algorytmu i korzystania z niego trzeba pami(cid:246)ta(cid:232) o diagramie z rysun- ku 7.1. Troch(cid:246) czasu po(cid:264)wi(cid:246)conego na zrozumienie kodu poprzez jego profilowanie powinno da(cid:232) mo(cid:276)liwo(cid:264)(cid:232) podj(cid:246)cia lepszych decyzji na poziomie algorytmicznym. Skoncentrowanie si(cid:246) w dalszej kolejno(cid:264)ci na kompilatorze powinno zaowocowa(cid:232) dodatkowym przyspieszeniem. Prawdopodobnie mo(cid:276)liwe b(cid:246)dzie dalsze dostrajanie algorytmu, ale nie nale(cid:276)y by(cid:232) zaskoczo- nym coraz mniejszymi przyspieszeniami wynikaj(cid:241)cymi z coraz wi(cid:246)kszej ilo(cid:264)ci w(cid:228)o(cid:276)onej pracy. Trzeba samemu stwierdzi(cid:232), kiedy dodatkowe starania przestan(cid:241) by(cid:232) op(cid:228)acalne. Rysunek 7.1. Troch(cid:246) czasu po(cid:264)wi(cid:246)conego na profilowanie i kompilowanie zapewnia spore korzy(cid:264)ci, ale dalsze dzia(cid:228)ania zwykle s(cid:241) coraz mniej op(cid:228)acalne Jakie wzrosty szybko(cid:316)ci s(cid:233) mo(cid:348)liwe? (cid:95) 135 Kup książkęPoleć książkę Je(cid:264)li u(cid:276)ywasz kodu Python i ca(cid:228)ej grupy do(cid:228)(cid:241)czonych bibliotek bez narz(cid:246)dzia numpy, podsta- wowymi opcjami wyboru b(cid:246)d(cid:241) narz(cid:246)dzia Cython, Shed Skin i PyPy. Je(cid:264)li u(cid:276)ywasz narz(cid:246)dzia numpy, odpowiednimi propozycjami s(cid:241) narz(cid:246)dzia Cython, Numba i Pythran. Obs(cid:228)uguj(cid:241) one j(cid:246)zyk Python 2.7, a cz(cid:246)(cid:264)(cid:232) z nich jest te(cid:276) zgodna z j(cid:246)zykiem Python w wersji 3.2 lub nowszej. Niektóre z przedstawionych dalej przyk(cid:228)adów wymagaj(cid:241) ogólnej znajomo(cid:264)ci kompilatorów kodu C oraz samego kodu C. W przypadku braku takiej wiedzy przed zag(cid:228)(cid:246)bieniem si(cid:246) w t(cid:246) tematyk(cid:246) powiniene(cid:264) w podstawowym zakresie pozna(cid:232) j(cid:246)zyk C i skompilowa(cid:232) dzia(cid:228)aj(cid:241)cy pro- gram napisany w tym j(cid:246)zyku. Porównanie kompilatorów JIT i AOT Omawiane narz(cid:246)dzia mo(cid:276)na podzieli(cid:232) na dwie grupy: s(cid:228)u(cid:276)(cid:241)ce do wcze(cid:264)niejszego kompilo- wania (kompilatory AOT: Cython, Shed Skin, Pythran) oraz do kompilowania przy pierwszej próbie u(cid:276)ycia kodu (kompilatory JIT: Numba, PyPy). Kompilowanie za pomoc(cid:241) kompilatora AOT (Ahead of Time) powoduje utworzenie biblioteki statycznej przeznaczonej dla u(cid:276)ywanej platformy sprz(cid:246)towej. Po pobraniu narz(cid:246)dzia numpy, scipy lub scikit-learn nast(cid:241)pi skompilowanie przez jedno z nich cz(cid:246)(cid:264)ci biblioteki z wykorzy- staniem kompilatora Cython na danej platformie sprz(cid:246)towej (ewentualnie w przypadku u(cid:276)y- cia dystrybucji takiej jak Continuum Anaconda, zostanie zastosowana wcze(cid:264)niej zbudowana biblioteka kompilowana). Dzi(cid:246)ki kompilacji kodu przed jego u(cid:276)yciem uzyskuje si(cid:246) bibliotek(cid:246), która mo(cid:276)e od razu zosta(cid:232) zastosowana przy rozwi(cid:241)zywaniu problemu. Kompilowanie za pomoc(cid:241) kompilatora JIT (Just in Time) w du(cid:276)ym stopniu (lub ca(cid:228)kowicie) eliminuje pocz(cid:241)tkowe dzia(cid:228)ania. Kompilator mo(cid:276)e rozpocz(cid:241)(cid:232) kompilacj(cid:246) tylko odpowiednich cz(cid:246)(cid:264)ci kodu w momencie ich u(cid:276)ycia. Oznacza to wyst(cid:241)pienie problemu zimnego startu. Polega on na tym, (cid:276)e mo(cid:276)e wyst(cid:241)pi(cid:232) sytuacja, gdy wi(cid:246)kszo(cid:264)(cid:232) kodu programu zosta(cid:228)a ju(cid:276) skompilo- wana, a aktualnie u(cid:276)ywana porcja kodu jeszcze nie, wi(cid:246)c w momencie rozpoczynania urucha- miania kodu w czasie trwania kompilacji b(cid:246)dzie on dzia(cid:228)a(cid:232) bardzo wolno. Je(cid:264)li ma to miejsce ka(cid:276)dorazowo przy uruchamianiu skryptu, który jest uaktywniany wielokrotnie, zwi(cid:241)zany z tym spadek wydajno(cid:264)ci mo(cid:276)e sta(cid:232) si(cid:246) znaczny. Poniewa(cid:276) problem ten dotyczy kompilatora PyPy, korzystanie z niego w przypadku krótkich, lecz cz(cid:246)sto wykonywanych skryptów mo(cid:276)e okaza(cid:232) si(cid:246) niepo(cid:276)(cid:241)dane. W tym miejscu omówienia wida(cid:232), (cid:276)e wcze(cid:264)niejsze kompilowanie daje korzy(cid:264)(cid:232) w postaci naj- lepszych przyspiesze(cid:254), ale cz(cid:246)sto wymaga te(cid:276) najwi(cid:246)kszego nak(cid:228)adu pracy. Kompilatory JIT oferuj(cid:241) du(cid:276)e przyspieszenia przy bardzo ma(cid:228)ej liczbie r(cid:246)cznie wprowadzanych zmian, ale mog(cid:241) powodowa(cid:232) opisany problem. Przy wyborze w(cid:228)a(cid:264)ciwej technologii na potrzeby konkretnego zastosowania konieczne b(cid:246)dzie rozwa(cid:276)enie tych kwestii. Dlaczego informacje o typie u(cid:293)atwiaj(cid:233) przyspieszenie dzia(cid:293)ania kodu? W j(cid:246)zyku Python typy s(cid:241) dynamicznie okre(cid:264)lane. Zmienna mo(cid:276)e odwo(cid:228)ywa(cid:232) si(cid:246) do obiektu do- wolnego typu, a dowolny wiersz kodu mo(cid:276)e zmieni(cid:232) typ przywo(cid:228)ywanego obiektu. Utrudnia to maszynie wirtualnej optymalizacj(cid:246) metody wykonywania kodu na poziomie kodu maszynowego, 136 (cid:95) Rozdzia(cid:293) 7. Kompilowanie do postaci kodu C Kup książkęPoleć książkę poniewa(cid:276) nie dysponuje ona informacj(cid:241) o tym, jaki podstawowy typ danych b(cid:246)dzie u(cid:276)ywany dla przysz(cid:228)ych operacji. Utrzymywanie kodu w uogólnionej postaci powoduje, (cid:276)e b(cid:246)dzie on d(cid:228)u(cid:276)ej wykonywany. W poni(cid:276)szym przyk(cid:228)adzie v identyfikuje liczb(cid:246) zmiennoprzecinkow(cid:241) lub par(cid:246) takich liczb, które reprezentuj(cid:241) liczb(cid:246) zespolon(cid:241) complex. Oba warunki mog(cid:241) wyst(cid:241)pi(cid:232) w tej samej p(cid:246)tli w ró(cid:276)nym czasie lub w powi(cid:241)zanych kolejnych sekcjach kodu: v = -1.0 print type(v), abs(v) type float 1.0 v = 1-1j print type(v), abs(v) type complex 1.41421356237 Funkcja abs dzia(cid:228)a ró(cid:276)nie w zale(cid:276)no(cid:264)ci od bazowego typu danych. Funkcja ta u(cid:276)yta dla liczby ca(cid:228)kowitej lub zmiennoprzecinkowej po prostu powoduje przekszta(cid:228)cenie warto(cid:264)ci ujemnej w warto(cid:264)(cid:232) dodatni(cid:241). W przypadku liczby zespolonej funkcja abs pobiera pierwiastek kwa- dratowy sumy elementów podniesionych do kwadratu: (cid:11) (cid:12) abs c (cid:32) c real . 2 (cid:14) c imag . 2 Kod maszynowy dla przyk(cid:228)adu liczby zespolonej complex uwzgl(cid:246)dnia wi(cid:246)cej instrukcji i do wykonania wymaga wi(cid:246)cej czasu. Przed wywo(cid:228)aniem funkcji abs dla zmiennej interpreter j(cid:246)- zyka Python musi najpierw poszuka(cid:232) typu zmiennej, a nast(cid:246)pnie zdecydowa(cid:232), jak(cid:241) wersj(cid:246) funkcji wywo(cid:228)a(cid:232). Zwi(cid:241)zane z tym obci(cid:241)(cid:276)enie zwi(cid:246)ksza si(cid:246) w przypadku wykonywania wielu powtarzanych wywo(cid:228)a(cid:254). W obr(cid:246)bie kodu Python ka(cid:276)dy podstawowy obiekt, taki jak liczba ca(cid:228)kowita, zostanie opa- kowany za pomoc(cid:241) obiektu j(cid:246)zyka Python wy(cid:276)szego poziomu (np. za pomoc(cid:241) obiektu int w przypadku liczby ca(cid:228)kowitej). Tego rodzaju obiekt oferuje dodatkowe funkcje, takie jak __hash__ (u(cid:228)atwia przechowywanie) i __str__ (obs(cid:228)uguje wy(cid:264)wietlanie (cid:228)a(cid:254)cuchów). Wewn(cid:241)trz sekcji kodu powi(cid:241)zanego z procesorem cz(cid:246)st(cid:241) sytuacj(cid:241) jest to, (cid:276)e typy zmiennych nie zmieniaj(cid:241) si(cid:246). Daje to mo(cid:276)liwo(cid:264)(cid:232) zastosowania kompilacji statycznej i szybszego wyko- nywania kodu. Je(cid:264)li wymaganych jest jedynie wiele po(cid:264)rednich operacji matematycznych, nie s(cid:241) potrzebne funkcje wy(cid:276)szego poziomu, a ponadto mog(cid:241) by(cid:232) zb(cid:246)dne mechanizmy s(cid:228)u(cid:276)(cid:241)ce do zliczania odwo(cid:228)a(cid:254). W tym przypadku mo(cid:276)na po prostu przej(cid:264)(cid:232) do poziomu kodu maszynowego i prze- prowadzi(cid:232) szybko obliczenia przy u(cid:276)yciu kodu maszynowego i bajtów, a nie poprzez mody- fikowanie obiektów wy(cid:276)szego poziomu j(cid:246)zyka Python, z czym wi(cid:241)(cid:276)e si(cid:246) wi(cid:246)ksze obci(cid:241)(cid:276)enie. W tym celu wcze(cid:264)niej okre(cid:264)lane s(cid:241) typy obiektów, aby mo(cid:276)liwe by(cid:228)o wygenerowanie po- prawnego kodu C. U(cid:348)ycie kompilatora kodu C W dalszych przyk(cid:228)adach zostan(cid:241) zastosowane kompilatory gcc i g++ z zestawu narz(cid:246)dziowego GNU C Compiler. Je(cid:264)li poprawnie skonfigurujesz (cid:264)rodowisko, mo(cid:276)esz skorzysta(cid:232) z alterna- tywnego kompilatora (np. icc Intela lub cl Microsoftu). Narz(cid:246)dzie Cython korzysta z kom- pilatora gcc, a narz(cid:246)dzie Shed Skin u(cid:276)ywa kompilatora g++. U(cid:348)ycie kompilatora kodu C (cid:95) 137 Kup książkęPoleć książkę Kompilator gcc stanowi znakomity wybór w przypadku wi(cid:246)kszo(cid:264)ci platform, poniewa(cid:276) jest dobrze obs(cid:228)ugiwany i do(cid:264)(cid:232) zaawansowany. Cz(cid:246)sto mo(cid:276)liwe jest uzyskanie wi(cid:246)kszej wydajno(cid:264)ci za pomoc(cid:241) dostrojonego kompilatora (np. w przypadku urz(cid:241)dze(cid:254) Intela kompilator icc tej firmy mo(cid:276)e wygenerowa(cid:232) szybszy kod ni(cid:276) kompilator gcc), ale wi(cid:241)(cid:276)e si(cid:246) to z konieczno(cid:264)ci(cid:241) poszerzenia wiedzy specjalistycznej i uzyskania informacji o sposobie dostosowywania flag dla alternatywnego kompilatora. J(cid:246)zyki C i C++ cz(cid:246)sto s(cid:241) u(cid:276)ywane do kompilacji statycznej w miejsce innych j(cid:246)zyków, takich jak Fortran, ze wzgl(cid:246)du na ich wszechobecno(cid:264)(cid:232) i bogat(cid:241) gam(cid:246) bibliotek pomocniczych. Kom- pilator i konwerter (w tym przypadku konwerterem jest narz(cid:246)dzie Cython i inne podobne) maj(cid:241) mo(cid:276)liwo(cid:264)(cid:232) analizowania kodu z adnotacj(cid:241) w celu okre(cid:264)lenia, czy mog(cid:241) zosta(cid:232) zastoso- wane kroki optymalizacji statycznej (np. wstawianie funkcji i rozwijanie p(cid:246)tli). Agresywna analiza po(cid:264)redniego drzewa sk(cid:228)adni abstrakcyjnej (przeprowadzana przez narz(cid:246)dzia Pythran, Numba i PyPy) zapewnia mo(cid:276)liwo(cid:264)ci (cid:228)(cid:241)czenia wiedzy o tym, jak w j(cid:246)zyku Python wyra(cid:276)ane s(cid:241) informacje o najlepszej metodzie wykorzystania napotkanych wzorców w celu przekaza- nia ich bazowemu kompilatorowi. Analiza przyk(cid:293)adu zbioru Julii W rozdziale 2. dokonano profilowania generatora zbioru Julii. U(cid:276)yty kod generuje obraz wyj- (cid:264)ciowy z wykorzystaniem liczb ca(cid:228)kowitych i liczb zespolonych. Obliczenia obrazu s(cid:241) powi(cid:241)- zane z procesorem. G(cid:228)ówne obci(cid:241)(cid:276)enie zwi(cid:241)zane z wykonywaniem kodu mia(cid:228)o posta(cid:232) powi(cid:241)zanej z procesorem p(cid:246)tli wewn(cid:246)trznej, która oblicza list(cid:246) output. Lista mo(cid:276)e mie(cid:232) posta(cid:232) kwadratowej tablicy pik- seli, w której ka(cid:276)da warto(cid:264)(cid:232) reprezentuje koszt wygenerowania piksela. Kod funkcji wewn(cid:246)trznej zosta(cid:228) zaprezentowany w przyk(cid:228)adzie 7.1. Przyk(cid:228)ad 7.1. Analiza powi(cid:241)zanego z procesorem kodu funkcji zbioru Julii def calculate_z_serial_purepython(maxiter, zs, cs): Obliczanie listy output za pomoc(cid:261) regu(cid:225)y aktualizacji zbioru Julii output = [0] * len(zs) for i in range(len(zs)): n = 0 z = zs[i] c = cs[i] while n maxiter and abs(z) 2: z = z * z + c n += 1 output[i] = n return output W przypadku laptopa jednego z autorów obliczenie oryginalnego zbioru Julii dla siatki 1000×1000 przy warto(cid:264)ci maxit równej 300 zaj(cid:246)(cid:228)o w przybli(cid:276)eniu 11 sekund (u(cid:276)yto implementacji czystego kodu Python wykonywanego za pomoc(cid:241) narz(cid:246)dzia CPython 2.7). 138 (cid:95) Rozdzia(cid:293) 7. Kompilowanie do postaci kodu C Kup książkęPoleć książkę Cython Cython (http://cython.org/) to kompilator, który przekszta(cid:228)ca kod Python z adnotacj(cid:241) typu w skompilowany modu(cid:228) rozszerzenia. Adnotacje typu przypominaj(cid:241) te stosowane w j(cid:246)zyku C. Takie rozszerzenie mo(cid:276)e by(cid:232) importowane za pomoc(cid:241) narz(cid:246)dzia import jako zwyk(cid:228)y modu(cid:228) j(cid:246)zyka Python. Cho(cid:232) rozpocz(cid:246)cie dzia(cid:228)a(cid:254) nie przysparza trudno(cid:264)ci, wi(cid:241)(cid:276)e si(cid:246) z tym koniecz- no(cid:264)(cid:232) poszerzania wiedzy w coraz wi(cid:246)kszym stopniu wraz z ka(cid:276)dym dodatkowym pozio- mem z(cid:228)o(cid:276)ono(cid:264)ci i optymalizacji. Przez jednego z autorów narz(cid:246)dzie to jest wykorzystywane do przekszta(cid:228)cania funkcji wymagaj(cid:241)cych wielu oblicze(cid:254) w szybszy kod. Wybra(cid:228) to narz(cid:246)dzie z powodu jego powszechnego u(cid:276)ycia, dojrza(cid:228)o(cid:264)ci i obs(cid:228)ugi interfejsu OpenMP. W przypadku standardu OpenMP mo(cid:276)liwe jest radzenie sobie z problemami dotycz(cid:241)cymi przetwarzania równoleg(cid:228)ego poprzez zastosowanie modu(cid:228)ów obs(cid:228)uguj(cid:241)cych wieloproceso- rowo(cid:264)(cid:232), które s(cid:241) uruchamiane w wielu procesorach jednego komputera. W(cid:241)tki s(cid:241) ukrywane przed kodem Python. Dzia(cid:228)aj(cid:241) za po(cid:264)rednictwem wygenerowanego kodu C. Kompilator Cython (opublikowany w 2007 r.) wywodzi si(cid:246) z kompilatora Pyrex (wprowa- dzonego w 2002 r.). Cython rozszerza mo(cid:276)liwo(cid:264)ci pierwotnych zastosowa(cid:254) kompilatora Pyrex. Biblioteki, które u(cid:276)ywaj(cid:241) kompilatora Cython, to: scipy, scikit-learn, lxml i zmq. Kompilator Cython mo(cid:276)e by(cid:232) stosowany za po(cid:264)rednictwem skryptu setup.py do kompilacji modu(cid:228)u. Mo(cid:276)e te(cid:276) zosta(cid:232) u(cid:276)yty interaktywnie w pow(cid:228)oce IPython, co umo(cid:276)liwia „magiczne” polecenie. Adnotacja typów jest zwykle przeprowadzana przez programist(cid:246), cho(cid:232) mo(cid:276)liwa jest pewna forma zautomatyzowanego tworzenia adnotacji. Kompilowanie czystego kodu Python za pomoc(cid:233) narz(cid:253)dzia Cython Prosta metoda rozpocz(cid:246)cia tworzenia kompilowanego modu(cid:228)u rozszerzenia uwzgl(cid:246)dnia trzy pliki. W przypadku u(cid:276)ycia zbioru Julii jako przyk(cid:228)adu s(cid:241) to nast(cid:246)puj(cid:241)ce pliki: (cid:120) Plik wywo(cid:228)uj(cid:241)cego kodu Python (spora cz(cid:246)(cid:264)(cid:232) wcze(cid:264)niej przedstawionego kodu zbioru Julii). (cid:120) Nowy plik .pyx z funkcj(cid:241) do skompilowania. (cid:120) Plik setup.py, który zawiera instrukcje wywo(cid:228)uj(cid:241)ce kompilator Cython do utworzenia mo- du(cid:228)u rozszerzenia. Przy u(cid:276)yciu tej metody wywo(cid:228)ywany jest skrypt setup.py w celu wykorzystania kompilatora Cython do skompilowania pliku .pyx do postaci skompilowanego modu(cid:228)u. W systemach unik- sowych skompilowany modu(cid:228) b(cid:246)dzie prawdopodobnie plikiem .so. W systemie Windows powinien to by(cid:232) plik .pyd (biblioteka j(cid:246)zyka Python przypominaj(cid:241)ca bibliotek(cid:246) DLL). W przypadku przyk(cid:228)adu zbioru Julii zostan(cid:241) zastosowane nast(cid:246)puj(cid:241)ce pliki: (cid:120) julia1.py. S(cid:228)u(cid:276)y do zbudowania list wej(cid:264)ciowych i wywo(cid:228)ania funkcji obliczeniowej. (cid:120) cythonfn.pyx. Zawiera funkcj(cid:246) powi(cid:241)zan(cid:241) z procesorem, dla której mo(cid:276)na utworzy(cid:232) adnotacje. (cid:120) setup.py. Zawiera instrukcje procesu budowania. Wynikiem uruchomienia skryptu setup.py jest mo(cid:276)liwy do zaimportowania modu(cid:228). W skrypcie julia1.py z przyk(cid:228)adu 7.2 wymagane jest jedynie wprowadzenie kilku drobnych zmian w celu zaimportowania nowego modu(cid:228)u za pomoc(cid:241) instrukcji import i wywo(cid:228)ania funkcji. Cython (cid:95) 139 Kup książkęPoleć książkę Przyk(cid:228)ad 7.2. Importowanie nowo skompilowanego modu(cid:228)u do g(cid:228)ównego kodu ... import calculate # zgodnie z definicj(cid:261) w skrypcie setup.py ... def calc_pure_python(desired_width, max_iterations): # ... start_time = time.time() output = calculate.calculate_z(max_iterations, zs, cs) end_time = time.time() secs = end_time - start_time print Czas trwania: , secs, s ... W przyk(cid:228)adzie 7.3 zaczniemy od czystego kodu Python bez adnotacji typu. Przyk(cid:228)ad 7.3. Niezmieniony czysty kod Python z pliku cythonfn.pyx (ze zmienionym rozszerzeniem na .py) dla skryptu setup.py kompilatora Cython # cythonfn.pyx def calculate_z(maxiter, zs, cs): Obliczanie listy output za pomoc(cid:261) regu(cid:225)y aktualizacji zbioru Julii output = [0] * len(zs) for i in range(len(zs)): n = 0 z = zs[i] c = cs[i] while n maxiter and abs(z) 2: z = z * z + c n += 1 output[i] = n return output Skrypt setup.py z przyk(cid:228)adu 7.4 jest krótki. Zdefiniowano w nim sposób przekszta(cid:228)cenia pliku cythonfn.pyx w plik calculate.so. Przyk(cid:228)ad 7.4. Skrypt setup.py przekszta(cid:228)ca plik cythonfn.pyx w kod C, który ma zosta(cid:232) skompilowany przez kompilator Cython from distutils.core import setup from distutils.extension import Extension from Cython.Distutils import build_ext setup( cmdclass = { build_ext : build_ext}, ext_modules = [Extension( calculate , [ cythonfn.pyx ])] ) Po uruchomieniu skryptu setup.py z przyk(cid:228)adu 7.5 z argumentem build_ext kompilator Cython poszuka pliku cythonfn.pyx i utworzy plik calculate.so. Przyk(cid:228)ad 7.5. Uruchamianie skryptu setup.py w celu zbudowania nowo skompilowanego modu(cid:228)u $ python setup.py build_ext --inplace running build_ext cythoning cythonfn.pyx to cythonfn.c building calculate extension gcc -pthread -fno-strict-aliasing -DNDEBUG -g -fwrapv -O2 -Wall -Wstrict-prototypes -fPIC -I/usr/include/python2.7 -c cythonfn.c -o build/temp.linux-x86_64-2.7/cythonfn.o gcc -pthread -shared -Wl,-O1 -Wl,-Bsymbolic-functions -Wl, -Bsymbolic-functions -Wl,-z, relro build/temp.linux-x86_64-2.7/cythonfn.o -o calculate.so 140 (cid:95) Rozdzia(cid:293) 7. Kompilowanie do postaci kodu C Kup książkęPoleć książkę Pami(cid:246)taj o tym, (cid:276)e jest to krok wykonywany r(cid:246)cznie. Gdy zaktualizujesz plik .pyx lub setup.py i zapomnisz ponownie uruchomi(cid:232) polecenie do budowania, nie b(cid:246)dzie dost(cid:246)pny zaktualizowany modu(cid:228) .so do zaimportowania. Je(cid:264)li nie masz pewno(cid:264)ci, czy kod zosta(cid:228) skompilowany, sprawd(cid:274) znacznik czasu pliku .so. W razie w(cid:241)tpliwo(cid:264)ci usu(cid:254) wygenerowane pliki kodu C oraz plik .so, a nast(cid:246)pnie zbuduj je ponownie. Argument --inplace nakazuje kompilatorowi Cython zbudowanie skompilowanego modu(cid:228)u w bie(cid:276)(cid:241)cym katalogu, a nie w osobnym katalogu build. Po zako(cid:254)czeniu procesu budowania dost(cid:246)pny b(cid:246)dzie plik cythonfn.c, który jest raczej ma(cid:228)o czytelny, a tak(cid:276)e plik calculate.so. Po uruchomieniu kodu z pliku julia1.py importowany jest skompilowany modu(cid:228). Na laptopie jednego z autorów zbiór Julii zosta(cid:228) obliczony w czasie wynosz(cid:241)cym 8,9 sekundy, a nie w bar- dziej typowym czasie równym 11 sekund. Jest to niewielki wzrost wydajno(cid:264)ci kosztem zni- komego nak(cid:228)adu pracy. U(cid:348)ycie adnotacji kompilatora Cython do analizowania bloku kodu W poprzednim przyk(cid:228)adzie pokazano, (cid:276)e mo(cid:276)liwe jest szybkie zbudowanie skompilowanego modu(cid:228)u. W przypadku intensywnych p(cid:246)tli i operacji matematycznych ju(cid:276) samo to cz(cid:246)sto pro- wadzi do wzrostu szybko(cid:264)ci. Oczywi(cid:264)cie nie nale(cid:276)y po omacku przeprowadza(cid:232) optymalizacji. Konieczne jest stwierdzenie, jaka cz(cid:246)(cid:264)(cid:232) kodu jest wolna, aby mo(cid:276)liwe by(cid:228)o zdecydowanie o tym, co wymaga wi(cid:246)kszego nak(cid:228)adu pracy. Kompilator Cython oferuje opcj(cid:246) tworzenia adnotacji, która zapewnia plik wyj(cid:264)ciowy HTML mo(cid:276)liwy do wy(cid:264)wietlenia w przegl(cid:241)darce. Do wygenerowania adnotacji u(cid:276)ywane jest po- lecenie cython -a cythonfn.pyx, które generuje plik wyj(cid:264)ciowy cythonfn.html. Po wy(cid:264)wietleniu w przegl(cid:241)darce zawarto(cid:264)(cid:232) pliku przypomina widoczn(cid:241) na rysunku 7.2. Podobny rysunek jest dost(cid:246)pny w dokumentacji kompilatora Cython (http://docs.cython.org/src/quickstart/cythonize.html). Rysunek 7.2. Kolorem wyró(cid:276)niono dane wyj(cid:264)ciowe funkcji bez adnotacji uzyskane za pomoc(cid:241) kompilatora Cython Dwukrotne klikni(cid:246)cie ka(cid:276)dego wiersza powoduje jego rozwini(cid:246)cie i wy(cid:264)wietlenie wygene- rowanego kodu C. Intensywniejszy (cid:276)ó(cid:228)ty kolor oznacza wi(cid:246)cej wywo(cid:228)a(cid:254) w obr(cid:246)bie maszyny wirtualnej j(cid:246)zyka Python, bardziej bia(cid:228)e wiersze natomiast wskazuj(cid:241) na kod C, który w mniej- szym stopniu przypomina kod Python. Celem jest usuni(cid:246)cie jak najwi(cid:246)kszej liczby (cid:276)ó(cid:228)tych wierszy i zako(cid:254)czenie dzia(cid:228)a(cid:254) z jak najmniejsz(cid:241) liczb(cid:241) bia(cid:228)ych wierszy. Cython (cid:95) 141 Kup książkęPoleć książkę Cho(cid:232) bardziej (cid:276)ó(cid:228)te wiersze oznaczaj(cid:241) wi(cid:246)cej wywo(cid:228)a(cid:254) w obr(cid:246)bie maszyny wirtualnej, nieko- niecznie spowoduje to wolniejsze dzia(cid:228)anie kodu. Ka(cid:276)de wywo(cid:228)anie w maszynie wirtualnej wi(cid:241)(cid:276)e si(cid:246) z obci(cid:241)(cid:276)eniem, ale dla wszystkich takich wywo(cid:228)a(cid:254) b(cid:246)dzie ono znaczne tylko w przy- padku wywo(cid:228)a(cid:254) wyst(cid:246)puj(cid:241)cych wewn(cid:241)trz du(cid:276)ych p(cid:246)tli. Wywo(cid:228)ania poza obr(cid:246)bem du(cid:276)ych p(cid:246)tli (np. wiersz kodu u(cid:276)ywany do utworzenia listy output na pocz(cid:241)tku funkcji) nie s(cid:241) kosz- towne w porównaniu z kosztem oblicze(cid:254) w p(cid:246)tli wewn(cid:246)trznej. Nie marnuj czasu na wiersze, które nie powoduj(cid:241) spowolnienia kodu. W przyk(cid:228)adzie wiersze z najwi(cid:246)ksz(cid:241) liczb(cid:241) wywo(cid:228)a(cid:254) w obr(cid:246)bie maszyny wirtualnej j(cid:246)zyka Python (najbardziej (cid:276)ó(cid:228)te) maj(cid:241) numery 4 i 8. Na podstawie wyników dotychczasowych ope- racji profilowania mo(cid:276)na stwierdzi(cid:232), (cid:276)e wiersz 8. zostanie prawdopodobnie wywo(cid:228)any ponad 30 milionów razy, dlatego jest znakomitym kandydatem do tego, by si(cid:246) na nim skoncentrowa(cid:232). Wiersze 9., 10. i 11. s(cid:241) prawie (cid:276)ó(cid:228)te. Ponadto wiadomo, (cid:276)e znajduj(cid:241) si(cid:246) w (cid:264)rodku intensywnej p(cid:246)tli wewn(cid:246)trznej. Ogólnie rzecz bior(cid:241)c, odpowiadaj(cid:241) za spor(cid:241) cz(cid:246)(cid:264)(cid:232) czasu wykonywania funkcji. Z tego powodu w pierwszej kolejno(cid:264)ci trzeba si(cid:246) nimi zaj(cid:241)(cid:232). Je(cid:264)li musisz przypomnie(cid:232) sobie, ile czasu trwa(cid:228)o wykonywanie tej sekcji kodu, zajrzyj do podrozdzia(cid:228)u „U(cid:276)ycie narz(cid:246)dzia line_profiler do pomiarów dotycz(cid:241)cych kolejnych wierszy kodu” z rozdzia(cid:228)u 2. Wiersze 6. i 7. s(cid:241) mniej (cid:276)ó(cid:228)te. Poniewa(cid:276) s(cid:241) wywo(cid:228)ywane tylko milion razy, maj(cid:241) znacznie mniejszy wp(cid:228)yw na ko(cid:254)cow(cid:241) szybko(cid:264)(cid:232). Oznacza to, (cid:276)e pó(cid:274)niej mo(cid:276)na skupi(cid:232) uwag(cid:246) na nich. Okazuje si(cid:246), (cid:276)e poniewa(cid:276) s(cid:241) one obiektami list, w(cid:228)a(cid:264)ciwie nic nie mo(cid:276)na zrobi(cid:232), aby skróci(cid:232) czas dost(cid:246)pu do nich. Jak wspomniano w podrozdziale „Cython i numpy”, wyj(cid:241)tkiem jest operacja polegaj(cid:241)ca na zast(cid:241)pieniu obiektów list tablicami narz(cid:246)dzia numpy, które zapewni(cid:241) niewielki przyrost szybko(cid:264)ci. Aby lepiej zrozumie(cid:232) (cid:276)ó(cid:228)te obszary, mo(cid:276)esz rozwin(cid:241)(cid:232) ka(cid:276)dy wiersz przez dwukrotne klikni(cid:246)- cie. Na rysunku 7.3 wida(cid:232), (cid:276)e do utworzenia listy output iterowana jest d(cid:228)ugo(cid:264)(cid:232) elementu zs. Powoduje to utworzenie obiektów j(cid:246)zyka Python, w przypadku których maszyna wirtualna tego j(cid:246)zyka zlicza odwo(cid:228)ania. Cho(cid:232) te wywo(cid:228)ania s(cid:241) kosztowne, tak naprawd(cid:246) nie maj(cid:241) wp(cid:228)ywu na czas wykonywania tej funkcji. Rysunek 7.3. Kod C ukryty w wierszu kodu Python 142 (cid:95) Rozdzia(cid:293) 7. Kompilowanie do postaci kodu C Kup książkęPoleć książkę Aby poprawi(cid:232) czas wykonywania funkcji, konieczne jest rozpocz(cid:246)cie deklarowania typów obiektów, które s(cid:241) uwzgl(cid:246)dniane w p(cid:246)tlach wewn(cid:246)trznych generuj(cid:241)cych du(cid:276)e obci(cid:241)(cid:276)enie. Dzi(cid:246)ki temu p(cid:246)tle te mog(cid:241) tworzy(cid:232) mniej do(cid:264)(cid:232) kosztownych wywo(cid:228)a(cid:254) kierowanych do maszyny wir- tualnej j(cid:246)zyka Python. W ten sposób oszcz(cid:246)dza si(cid:246) czas. Ogólnie rzecz bior(cid:241)c, do wierszy kodu, które prawdopodobnie zajmuj(cid:241) najwi(cid:246)cej czasu pro- cesora, zaliczaj(cid:241) si(cid:246) nast(cid:246)puj(cid:241)ce: (cid:120) wiersze znajduj(cid:241)ce si(cid:246) w intensywnych p(cid:246)tlach wewn(cid:246)trznych, (cid:120) wiersze usuwaj(cid:241)ce odwo(cid:228)ania do elementów obiektów list, array lub np.array, (cid:120) wiersze wykonuj(cid:241)ce operacje matematyczne. Je(cid:264)li nie wiesz, jakie wiersze s(cid:241) najcz(cid:246)(cid:264)ciej wykonywane, wykorzystaj narz(cid:246)dzie do profilowania line_profiler, które omówiono w podrozdziale „U(cid:276)ycie narz(cid:246)dzia line_profiler do pomiarów dotycz(cid:241)cych kolejnych wierszy kodu” z rozdzia(cid:228)u 2. Dowiesz si(cid:246), jakie wiersze s(cid:241) najcz(cid:246)(cid:264)ciej wykonywane, a tak(cid:276)e które z nich powoduj(cid:241) najwi(cid:246)ksze obci(cid:241)(cid:276)enie wewn(cid:241)trz maszyny wirtualnej j(cid:246)zyka Python. Dzi(cid:246)ki temu uzyskasz wyra(cid:274)ny dowód na to, jakie wiersze wymagaj(cid:241) uwagi w celu osi(cid:241)gni(cid:246)cia najlepszego przyrostu szybko(cid:264)ci. Dodawanie adnotacji typu Na rysunku 7.2 pokazano, (cid:276)e prawie ka(cid:276)dy wiersz funkcji jest wywo(cid:228)ywany w maszynie wirtualnej j(cid:246)zyka Python. Wszystkie obliczenia numeryczne równie(cid:276) s(cid:241) wywo(cid:228)ywane w tej maszynie, poniewa(cid:276) u(cid:276)ywane s(cid:241) obiekty j(cid:246)zyka Python wy(cid:276)szego poziomu. Konieczne jest przekszta(cid:228)cenie tych obiektów w lokalne obiekty j(cid:246)zyka C, a nast(cid:246)pnie, po przeprowadzeniu kodowania numerycznego, przekszta(cid:228)cenie wyniku z powrotem w obiekt j(cid:246)zyka Python. W przyk(cid:228)adzie 7.6 widoczny jest sposób dodawania typów podstawowych za pomoc(cid:241) sk(cid:228)adni s(cid:228)owa kluczowego cdef. Przyk(cid:228)ad 7.6. Dodawanie typów podstawowych j(cid:246)zyka C w celu rozpocz(cid:246)cia przyspieszania dzia(cid:228)ania skompilowanej funkcji. W tym celu u(cid:276)ywany jest w wi(c
Pobierz darmowy fragment (pdf)

Gdzie kupić całą publikację:

Python. Programuj szybko i wydajnie
Autor:
,

Opinie na temat publikacji:


Inne popularne pozycje z tej kategorii:


Czytaj również:


Prowadzisz stronę lub blog? Wstaw link do fragmentu tej książki i współpracuj z Cyfroteką: