Alat atau pendekatan apa yang tersedia untuk mempercepat kode yang ditulis dengan Python?

29

Latar Belakang: Saya pikir saya mungkin ingin mem-porting beberapa kode yang menghitung produk matriks eksponensial-vektor menggunakan metode subruang Krylov dari MATLAB ke Python. (Secara khusus, fungsi expmvp Jitse Niesen , yang menggunakan algoritma yang dijelaskan dalam makalah ini .) Namun, saya tahu bahwa kecuali saya menggunakan banyak fungsi dari modul yang berasal dari perpustakaan yang dikompilasi (yaitu, saya hanya menggunakan Python mentah, dan tidak banyak built-in dalam fungsi), maka itu bisa sangat lambat.

Pertanyaan: Alat atau pendekatan apa yang tersedia untuk membantu saya mempercepat kode yang saya tulis dengan Python untuk kinerja? Secara khusus, saya tertarik pada alat yang mengotomatiskan proses sebanyak mungkin, meskipun pendekatan umum juga diterima.

Catatan: Saya memiliki versi algoritma Jitse yang lebih lama, dan belum pernah menggunakannya untuk sementara waktu. Ini bisa sangat mudah untuk membuat kode ini cepat, tetapi saya merasa itu akan menjadi contoh nyata yang baik, dan ini terkait dengan penelitian saya sendiri. Memperdebatkan pendekatan saya untuk mengimplementasikan algoritma khusus ini di Python adalah pertanyaan lain sepenuhnya.

Geoff Oxberry
sumber
Saya memberikan jawaban Python-sepcific untuk pertanyaan ini: scicomp.stackexchange.com/questions/2429/... Saya pikir petunjuk dan tautan di sana akan membantu Anda.
AlexE
(h / t ke @AlexE untuk membuat saya sadar akan hal ini) Pasti ada tumpang tindih di antara pertanyaan ini, (bagaimana) menulis simulasi yang berjalan lebih cepat? , dan Apa sajakah strategi yang baik untuk meningkatkan kinerja serial kode saya? . Semacam penggabungan bisa dilakukan. Saya memposting tentang itu di Meta.
Geoff Oxberry
1
Selain jawaban yang bagus di sini, lihat tautan ini .
Mike Dunlavey

Jawaban:

40

Saya akan memecah jawaban saya menjadi tiga bagian. Profiling, mempercepat kode python melalui c, dan mempercepat python melalui python. Ini adalah pandangan saya bahwa Python memiliki beberapa alat terbaik untuk melihat kinerja kode Anda kemudian menelusuri hingga ke leher botol yang sebenarnya. Mempercepat kode tanpa membuat profil adalah seperti mencoba membunuh rusa dengan uzi.

Jika Anda benar-benar hanya tertarik pada produk mat-vec, saya akan merekomendasikan scipy.sparse .

Alat Python untuk pembuatan profil

profil dan modul cProfile : Modul -modul ini akan memberi Anda analisis run time standar dan tumpukan panggilan fungsi. Cukup bagus untuk menyimpan statistik mereka dan menggunakan modul pstats Anda dapat melihat data dalam beberapa cara.

kernprof : alat ini menyatukan banyak rutinitas untuk melakukan hal-hal seperti penentuan kode baris per baris

memory_profiler : alat ini menghasilkan cetakan memori baris per baris kode Anda.

Pengatur waktu IPython :timeitFungsi ini cukup baik untuk melihat perbedaan fungsi dengan cara interaktif cepat.

Mempercepat Python

Cython : cython adalah cara tercepat untuk mengambil beberapa fungsi dalam python dan mendapatkan kode lebih cepat. Anda dapat menghias fungsi dengan varian cython python dan menghasilkan kode c. Ini sangat mudah dikelola dan juga dapat menghubungkan ke kode tulisan tangan lain di c / c ++ / fortran dengan mudah. Ini adalah alat yang paling disukai saat ini.

ctypes : ctypes akan memungkinkan Anda untuk menulis fungsi Anda di c dan kemudian membungkusnya dengan cepat dengan dekorasi kode yang sederhana. Ini menangani semua rasa sakit dari casting dari PyObjects dan mengatur gil untuk memanggil fungsi c.

Pendekatan lain ada untuk menulis kode Anda dalam C tetapi mereka semua agak lebih untuk mengambil perpustakaan C / C ++ dan membungkusnya dengan Python.

Pendekatan hanya-python

Jika Anda sebagian besar ingin tetap berada di dalam Python, saran saya adalah mencari tahu data apa yang Anda gunakan dan memilih tipe data yang benar untuk mengimplementasikan algoritma Anda. Sudah pengalaman saya bahwa Anda biasanya akan mendapatkan lebih jauh dengan mengoptimalkan struktur data Anda kemudian c hack tingkat rendah. Sebagai contoh:

numpy : array kontingous yang sangat cepat untuk operasi array yang cepat

numexpr : pengoptimal ekspresi array yang numpy. Hal ini memungkinkan untuk ekspresi array numpy multithreading dan juga menghilangkan banyak temporer membuat numpy karena pembatasan juru bahasa Python.

blist : implementasi b-tree dari daftar, sangat cepat untuk menyisipkan, mengindeks, dan memindahkan node internal daftar

panda : kerangka data (atau tabel) analitik yang sangat cepat pada array.

pytables : tabel hierarki terstruktur cepat (seperti hdf5), terutama bagus untuk perhitungan inti dan kueri untuk data besar.

aterrel
sumber
3
Anda dapat menggunakan ctypes untuk memanggil rutinitas Fortran juga.
Matthew Emmett
Bicara tentang kode pembungkus, bagaimana dengan f2py?
astrojuanlu
f2py adalah alat yang hebat dan digunakan oleh banyak orang di komunitas. fwrap adalah pengganti yang lebih baru karena f2py menunjukkan umurnya tetapi tidak benar-benar lengkap.
aterrel
Terima kasih! Ini adalah jenis sumber daya yang saya cari. Saya hanya mengetahui beberapa dari mereka, dan hanya lewat (atau dari melihat mereka di Internet). Aron terus menyebutkan numexpr. Bagaimana cara kerjanya? Apakah itu berlaku?
Geoff Oxberry
7

Pertama-tama, jika ada implementasi C atau Fortran (fungsi MATLAB MEX?), Mengapa Anda tidak menulis pembungkus Python?

Jika Anda ingin implementasi Anda sendiri tidak hanya pembungkus, saya akan sangat menyarankan untuk menggunakan modul numpy untuk hal-hal aljabar linier. Pastikan itu ditautkan ke blas yang dioptimalkan (seperti ATLAS, GOTOblas, uBLAS, Intel MKL, ...). Dan gunakan Cython atau menenun. Baca artikel Python Performa ini untuk pengenalan dan tolok ukur yang baik. Berbagai implementasi dalam artikel ini tersedia untuk diunduh di sini atas izin Travis Oliphant (Numpy-guru).

Semoga berhasil.

GertVdE
sumber
Artikel Kinerja Python itu tampaknya sedikit ketinggalan zaman, tidak menyebutkan beberapa alat yang lebih baru yang tersedia seperti numexpr.
Aron Ahmadia
Saya memang mengabaikan numexpr. Akan menyenangkan untuk menjalankan patokan laplace yang sama dengan numexpr ...
GertVdE
Apakah scipy.weavemasih digunakan dan dikembangkan? Tampaknya artikel Kinerja Python menunjukkan bahwa itu bisa cepat digunakan dan memberikan peningkatan kecepatan yang cukup bagus tapi saya jarang melihatnya disebutkan di luar artikel itu.
Ken
@ Ken: scipy.weave, sejauh yang saya tahu, tidak lagi dalam pengembangan aktif. Itu disimpan untuk kompatibilitas mundur tetapi proyek-proyek baru didorong untuk menggunakan Cython.
GertVdE
Untuk GotoBLAS dan NumPy / SciPy, lihat der-schnorz.de/2012/06/optimized-linear-algebra-and-numpyscipy
AlexE
4

Pada dasarnya saya setuju dengan jawaban yang lain. Pilihan terbaik untuk pythonkode numerik cepat adalah

  • Gunakan perpustakaan khusus seperti numpy
  • bungkus kode yang ada sehingga python-program Anda dapat memanggilnya secara langsung

Tetapi jika Anda ingin memprogram seluruh algoritma dari awal (saya kutip: "Saya hanya menggunakan Python mentah") maka Anda mungkin ingin mempertimbangkan http://pypy.org/ sebuah implementasi JIT (Just In Time) dari python. Saya belum bisa menggunakannya untuk proyek saya (karena itu bergantung numpydan pypyorang-orang benar-benar bekerja mendukungnya) tetapi tolok ukurnya cukup mengesankan ( http://speed.pypy.org/ )

bgschaid
sumber