Bagaimana cara membuat kode python saya berjalan lebih cepat 10x?

Meskipun Python adalah salah satu bahasa pemrograman paling populer di dunia, itu bukannya tanpa kekurangan. Yang terbesar? . Kode python dikompilasi menjadi bytecode oleh CPython dan kemudian dieksekusi oleh juru bahasa. Mudah untuk dipelajari? . Cepat? .  

Sampai Anda mengedit kode sumber Anda, bytecode di-cache di a. berkas pyc; . Lari kedua dan selanjutnya lebih baik untuk menilai kecepatan

Berikut adalah lima cara untuk meningkatkan kode Python Anda. Saya telah mengujinya menggunakan Python 3. 7 dan 3. 9; . Saya telah menggunakan fungsi perf_counter_ns dari paket waktu untuk melakukan semua pengaturan waktu dalam nanodetik.  

Jadilah Pythonic

Sangat mudah, berasal dari bahasa pemrograman lain, untuk menulis kode yang memotong arus. Menggunakan for loop atau array, misalnya, dan kode Anda akan berjalan lambat. Cara Python dalam melakukan sesuatu (a. k. a. Pythonic) menggunakan fitur seperti peta, pemahaman daftar, dan generator. Dan jangan lupakan fungsi berguna seperti jumlah dan rentang.   

Misalnya, jika Anda ingin membandingkan dua cara untuk menjumlahkan semua int dalam rentang 1-100 yang habis dibagi 3

from time import perf_counter_ns

def main():    
    # non pythonic
    start=perf_counter_ns()
    total=0 
    for i in range(1,100):
        if (i %3)== 0:
            total += i
    end=perf_counter_ns()      
    print (f"Non-Pythonic Total of divisible by 3= {total}")
    print(f"Time took {end-start}")

    # pythonic
    start=perf_counter_ns()
    total =sum(range(1, 100, 3))
    end=perf_counter_ns()      
    print (f"Pythonic Total of divisible by 3= {total}")
    print(f"Time took {end-start}")

if __name__ == "__main__":
    main()

Ini memberi Anda

Non-Pythonic Total of divisible by 3= 1683
Time took 13300
Pythonic Total of divisible by 3= 1683
Time took 2900
_

Ini adalah waktu putaran kedua. Lari pertama adalah 14.500 dan 3.000, jadi antara 3. 5 persen dan 9 persen lebih lama (perhatikan bahwa cara Pythonic hampir lima kali lebih cepat).  

Gunakan memoisasi

Ini terdengar lebih rumit dari yang sebenarnya. Jika biaya pemanggilan suatu fungsi tinggi, menambahkan "menghafal" berarti hasilnya di-cache; . Ini dapat memberikan peningkatan kecepatan yang sangat besar.  

Paket functools memiliki lru_cache, yang dapat Anda gunakan untuk menghias fungsi yang ingin Anda buat memo. Pada contoh di bawah ini, fib adalah fungsi fibonacci non-memo sederhana, dan fib(35) melakukan banyak penambahan; .  

from time import perf_counter_ns
from functools import lru_cache

def main():    
    def fib(n):
        return n if n < 2 else fib(n-1) + fib(n-2)

    @lru_cache(maxsize=None)
    def mfib(n):
        return n if n < 2 else mfib(n-1) + mfib(n-2)
    start=perf_counter_ns()
    print(f"Non-memoized fib()={fib(35)}")
    end=perf_counter_ns()      
    print(f"Time took {end-start}")

    start=perf_counter_ns()  
    print(f"Memoized fib()={mfib(35)}")
    end=perf_counter_ns()      
    print(f"Time took {end-start}")

if __name__ == "__main__":
    main()

Hasilnya berbicara sendiri

Non-memoized fib()=9227465
Time took 2905175700
Memoized fib()=9227465
Time took 148700

Itu hampir 20.000 kali lebih cepat

Saya penasaran dengan jumlah penambahannya. Jumlah total penambahan #(x) = #(x-1)+#(x-2)+1 di mana #(n) adalah jumlah penambahan untuk n. Dimulai dengan fib(2), Anda mendapatkan urutan total penambahan 1, 2, 4, 7, 12…, dan untuk fib(35) ada penambahan 14.930.351 kekalahan.   

Pengembang Oren Tosh berpendapat bahwa dia dapat menyempurnakannya dengan secara diam-diam menggunakan subkelas Kamus dengan metode dunder __missing__.  

Kodekan dalam C

Ini tidak selalu mudah dilakukan. Anda harus tahu C dan bagaimana antarmuka dengan Python. Juga, mungkin hanya ada beberapa kasus di mana pengkodean dalam C akan berhasil. Ini membantu bahwa CPython ditulis dalam C.  

Ada library tipe C dan pemetaan Python-nya di library ctypes. Pustaka ini juga memungkinkan Anda melakukan panggilan ke pustaka sistem operasi, tetapi Anda harus merasa nyaman bekerja pada tingkat yang cukup rendah dan mengetahui C termasuk larik, struct, dan penunjuk sebelum Anda pergi ke sana.  

Kompilasi Python

Kode mesin yang Anda buat saat mengkompilasi kode akan selalu berjalan lebih cepat daripada bytecode yang ditafsirkan. Anda akan menemukan beberapa compiler Python yang tersedia termasuk Numpa, Nuitka, pypi dan Cython. Saya belum mencoba semua ini tetapi menyarankan Anda mengoptimalkan kode Python Anda sebelum mencoba mengompilasinya. Kompiler Numpa adalah JIT (Just-In-Time) dan juga menyediakan akselerasi bertenaga GPU.  

Gunakan 'Dari' jika memungkinkan

Terlalu mudah untuk menggunakan paket impor sepanjang waktu. Namun lebih masuk akal untuk menggunakan dari saat Anda bisa hanya mengimpor fungsi yang diperlukan. Mengapa mengimpor dua puluh fungsi saat Anda hanya membutuhkan satu?

from time import perf_counter_ns

def main():
    start=perf_counter_ns()
    n = 10
    fact = 1
  
    for i in range(1,n+1):
        fact = fact * i
    end=perf_counter_ns()      
    print (f"The factorial of {n} is {fact}")
    print(f"Time took {end-start}")

if __name__ == "__main__":
    main()
_

Proses pertama ini adalah 4200 nanodetik, tetapi proses selanjutnya sekitar 3900. Selain itu, jangan lupa Anda dapat memasukkan impor ke dalam fungsi sehingga hanya dipanggil saat dibutuhkan

Kesimpulan

Jika ada satu metode untuk dipilih, gunakan memoisasi untuk mendapatkan kecepatan terbaik dari Python—tetapi Anda mungkin akan menjadi pemrogram Python yang lebih baik jika Anda mempelajari pendekatan pythonic

Sangat menarik melihat rencana untuk membuat CPython hingga lima kali lebih cepat selama empat rilis berikutnya. Apakah itu bisa dilakukan adalah tebakan siapa pun, tetapi jika itu terjadi, itu akan membuat Python tetap di tempat nomor satu untuk popularitas untuk waktu yang sangat lama.

Metode lain yang diusulkan untuk meningkatkan kecepatan Python adalah membuat kode multithread lebih cepat dengan menghapus GIL (Global Interpreter Lock). Ini adalah mutex yang hanya memungkinkan satu utas untuk memegang kendali juru bahasa Python. Jika Anda menulis kode multithreaded yang tidak menggunakan Gil, itu tidak dapat mengakses variabel dan objek Python.  

Daftar Sekarang

Keanggotaan memiliki manfaat. Daftar untuk mendapatkan profil Dice gratis, tambahkan resume Anda, temukan wawasan karier yang hebat, dan atur karier teknologi Anda. Daftar sekarang

Bisakah Python dipercepat?

Dibandingkan bekerja dengan bahasa seperti C dan C++, Python terkadang terasa terlalu lambat. Untungnya ada beberapa pustaka fantastis dan fungsi bawaan yang dapat mempercepat kode Python .

Mengapa Python sangat lamban?

Tidak seperti bahasa pemrograman populer lainnya termasuk C# atau JAVA, Python diketik secara dinamis dan merupakan bahasa yang ditafsirkan. Lambat terutama karena sifat dinamis dan keserbagunaannya .

Bagaimana saya bisa mempercepat kode saya?

5 Teknik Sederhana untuk Menulis Kode Anda Lebih Efisien dengan Python. Jadikan kode Anda lebih cepat, lebih mudah dibaca, dan lebih mudah dipahami. .
Membuat Fungsi. .
Hilangkan Operasi yang Tidak Penting. .
Gunakan Paket untuk Keuntungan Anda. .
Hindari Mendeklarasikan Variabel yang Tidak Perlu. .
Putuskan Loop Bila Diperlukan

Bagaimana cara menjalankan kode Python secara bersamaan?

Solusi paling sederhana untuk menjalankan dua proses Python secara bersamaan adalah menjalankannya dari file bash, dan memberi tahu setiap proses untuk masuk ke latar belakang dengan operator & shell. .
Apakah kedua skrip ini berjalan secara paralel?.
@Snedecor, ini tampaknya berjalan secara paralel, melainkan setiap skrip berjalan secara bersamaan