+− THE DAILY DIFFdev & AI news
SHIP IT

Python performansı: yerel NumPy döngüleri, geri aramalar ve dönüştürme maliyetleri

Kontrollü, yalnızca CPU'lu bir sayısal test, CPython döngüleri, NumPy aritmetiği, bir Python geri çağrı sarmalayıcısı ve derlenmiş bir Numba döngüsü aracılığıyla aynı değerleri takip eder.

Want to see our stories first on Google? Add us to your preferred sources — it helps us grow.

Kontrollü, yalnızca CPU'lu bir sayısal test, CPython döngüleri, NumPy aritmetiği, bir Python geri çağrı sarmalayıcısı ve derlenmiş bir Numba döngüsü aracılığıyla aynı değerleri takip eder. Hazır girişli NumPy büyük bir avantaja sahipti, ancak Python listelerine dönüştürme ve geri dönüştürme, bu avantajı neredeyse bir beraberliğe indirdi. Bölüm, yürütme sınırını ve bir uygulamanın ihtiyaç duyduğu sonucu nasıl ölçeceğinizi açıklar.

Yazılı sürümü oku (İngilizce) ↗

Bu video neleri kapsar

  • CPython, kaynağı bayt koduna derler. Tekrarlanan yorumlayıcı/nesne çalışması ve tip tanımlı bir yerel sayısal döngü farklı yürütme düzenlemeleridir.
  • Sayısal NumPy aritmetiği, derlenmiş işlemlere tip tanımlı yığınlar verebilir; aritmetik döngü hala mevcuttur ve görünümler bitişik olmayan düzenlere sahip olabilir.
  • Dönüşümü ve gerekli çıktı temsilini ölçün. Bu çalıştırmada, Python listelerini dizilere dönüştürmek ve geri dönüştürmek, büyük hazır dizi avantajını sildi.
  • Küçük iş yükleri, sabit dizi çağrı maliyetleri önemli olduğu için sıradan Python'ı tercih edebilir. Sekiz değerli kavrama, ölçülen bu karşılaştırmayı kazandı.
  • np.vectorize, ardışık elemanlar için Python'u çağıran bir kolaylık sarmalayıcısıdır; yalnızca bir yığın arayüzü, yerel sayısal yürütmeyi sağlamaz.
  • Derlenmiş Python-sözdizimi döngüleri de hızlı olabilir. Çağıran için önemli olduğunda soğuk derleme/kurulum maliyetlerini dahil edin.
  • Yerel yürütme, CPU SIMD, çoklu iş parçacığı ve GPU arka uçları ayrı fikirlerdir. Mevcut CPU özellikleri, belirli bir çalıştırmada kullanılan talimatları izlemez.

Çevrilmiş deşifre

Orijinal İngilizce anlatımdan çevrilmiştir. Mevcut ses ve altyazılar YouTube tarafından kontrol edilir.

Aynı CPU neden daha erken bitirebilir?

0:00 Python'ın hızlanmak için yeni bir dile ihtiyacı olduğunu düşünüyorsunuz. Döngü taşındıktan sonra aynı CPU yığınımızı daha hızlı çalıştırdı. İş nereye gitti? Hızlanma ne zaman kaybolur? Python'ı geri getiren kısayol hangisi? Bu, The Daily Diff, perde arkasından. Bu kısayola dikkat edin. CPython, standart Python uygulamasıdır.

0:17 Kaynağınızı bayt koduna derler, ardından bu talimatları bir yorumlayıcıda çalıştırır. NumPy, dizileri beyan edilmiş bir veri türüne sahip değerleri tutan sayısal bir kütüphanedir. Duyuru yapılmış bir veri türü. Yerleşik aritmetiği, derlenmiş işlemlere bütün bir yığını verebilir. Bir milyon kayan noktalı değer alın, her birini kareleyin, sonra orijinal değeri ekleyin. Her sürüm aynı değerleri alır ve eşleşen cevaplar üretir. Değerler, yuvarlama farklılıklarını yarışın dışında tutacak kadar küçüktür.

0:40 Bu makinede, kavrama yaklaşık otuz üç milisaniye sürdü. NumPy bir saniyeden az sürdü. İkisi de CPU'da çalıştı. Bu iş yükü için faydalı bir kanıt ve bir programlama dili için korkunç bir ölüm ilanı. Sıradan döngüyle başlayın.

Bir Python döngüsü hangi işi tekrarlar?

0:53 Python bir sonraki değeri alır, aritmetik işlemi yapar ve cevabı ekler. Sonra bunu tekrar yapar. Çarpma ucuzdur. Bir sonraki çarpmayı ayarlamak ve etrafındaki Python nesnelerini ele almak, her seferinde iş ekler. Bu, test edilen fonksiyonun gerçek sökülmüş halidir. İterasyon, çarpma ve toplama bayt kodu talimatları olarak görünür. Python sürümleri ve yorumlayıcılar farklı seçimler yapar.

1:14 Bu zamanlamalar ekrandaki Python üç nokta on sürümüne aittir. Bir Python listesi nesne referanslarını saklar, böylece farklı türden şeyler bir listeyi paylaşabilir. Aritmetik işimiz boyunca sayıları kullanır. Tekrarlayan bir hizmet isterken genel bir düzenleme için ödeme yapar. Aynı kahveyi bir milyon kez sipariş ettiğinizi ve her fincan için yeni bir form doldurduğunuzu hayal edin. Kahve makinesi iyi durumda.

1:36 Evrak işleri kendi kariyerini geliştirdi.

NumPy döngüyü nereye taşıyor?

1:38 NumPy sözleşmeyi değiştirir. Bu dizi, beyan edilmiş tek bir türe sahip sabit boyutlu kayan noktalı değerler tutar. Dizimiz bitişiktir, bu yüzden değerleri bellekte yan yana durur. Görünümler başka düzenlere sahip olabilir. Aritmetik işlem, hangi tür veriyi aldığını bilir. Çağrı, yığını yerel bir işleme devreder. Bir döngü, derlenmiş kod içindeki değerleri hala ziyaret eder. Bu iş boyunca tür bilgisini yeniden kullanabilir.

2:00 Python, işi devreden kişi olarak kalır. Itamar Turner Trauring, Python Speed'deki ayrımı açıklıyor. Yığın arayüzleri, yerel uygulamalar ve işlemci vektör talimatları ayrı şeylerdir. Fonksiyon adı çok az kanıt sağlar.

Hızlı demek GPU mu, yoksa birçok CPU çekirdeği mi?

2:13 Bu sonuç CPU'da NumPy kullandı. CuPy gibi bir GPU arka ucu, diziler ve işlemler için farklı bir yer seçer. Bir GPU satın almak, bu sıradan Python döngüsünü zaten çalıştığı yerde çalışmaya bırakır. CPU vektör talimatları birkaç değeri birlikte işleyebilir. NumPy, desteklenen çekirdekleri seçmek için mekanizmalara sahiptir. Çalışma zamanımız mevcut özellikleri bildirir, ancak bu ifadenin talimatlarını izlemez. Tüm ölçülen kazanımı vektör talimatlarına vermek, kanıtı abartmak olur.

2:40 GPU alışveriş sepeti kapalı kalabilir. Bir satın almayı da iptal eden bir performans düzeltmesi hakkında derin bir tatmin duygusu var. Ne yazık ki, kıyaslama devam ediyor.

Etkileyici hızlanma ne zaman kaybolur?

2:49 Sekiz değerle, kavrama kazandı. Dizi mekanizmasını çağırmak, küçük işten daha pahalıya mal oldu. Daha büyük hazır diziler öne geçti. Tekrarlanan denemeler ve ısıtılmış bir süreç kullandık. Daha yeni Python derlemeleri geçişi değiştirebilir. Sonra uygulamanın neye ihtiyacı olduğunu değiştirin. Bir Python listesiyle başlayın ve yeni bir Python listesiyle bitirin. NumPy, girişi bir diziye dönüştürmeli ve cevabı tekrar Python nesnelerine

3:11 dönüştürmelidir. Uygulamanız bunları ihtiyaç duyuyorsa, bu adımlar faturaya aittir. Bir milyon değerde, bu tam yol yaklaşık yirmi sekiz milisaniye sürdü. Kavrama da yaklaşık yirmi sekiz sürdü. Dramatik liderliğimiz neredeyse bir beraberliğe dönüştü. Hızlı kısım gerçekti. Avantaj, verilerin sayısal biçiminde kalmasına izin vermeye bağlıydı.

Kıyaslamaya hangi sınırlar dahil edilmeli?

3:28 Verileri takip edin. Bir sonraki işlem bir diziyi kabul ediyorsa, diziyi tutun. Listeler ve diziler arasında tekrar tekrar dönüşüm yaparsanız, bu geçişleri ölçün. Pahalı bir aktarım öncesinde durmak, yanlış soru için doğru sayılar verir. Bu diziyi çarpmak geçici bir sonuç oluşturur. Orijinal değerleri eklemek çıktıyı oluşturur. Yerel yürütme hala belleğe ihtiyaç duyar ve veri taşır.

3:47 Bazı işlemler bir çıktı arabelleği kabul eder, kodunuz güvenle yeniden kullanabiliyorsa tahsisleri azaltır. Bir güzel satır birkaç büyük arabellek sipariş edebilir. Python Speed de bu sorunu işaret ediyor. Tahsis edici, estetiğinize karşı oldukça kayıtsızdır.

Derlenmiş bir Python döngüsü de hızlı olabilir mi?

4:00 Döngü sözdizimini de koruyabilir ve yürütmeyi değiştirebilirsiniz. Numba, desteklenen sayısal Python fonksiyonlarını yerel koda derleyebilir. İşte test döngümüzün derleyici dekoratörü ile birlikte. Hala için diyor. Pahalı yorumlayıcı yolu değişti. Derlemeden sonra, bu döngü hazır dizilerle yarım milisaniyeden daha az sürdü. Derleme ise bu çalıştırmada yaklaşık bir saniye sürdü. Bu kurulum maliyeti tekrarlanan zamanlamalardan hariç tutuldu,

4:22 bu nedenle küçük tek seferlik bir iş farklı bir karşılaştırmayı hak eder. Numba'nın kendi kılavuzu açık döngüleri göstermekten çekinmiyor. Sıcak yolu bulmadan bir dil geçişine başlamak, bir profilleyici açmaktan kaçınmanın karmaşık bir yoludur. bir profilleyici açmaktan kaçınmak. Önce zamanı neyin tükettiğini bulun. Ağ beklemeleri, nesne ayrıştırma ve toplu aritmetik farklı düzeltmeler gerektirir. Hesaplama ve veriler uyduğunda yerel dizi işlemleri yardımcı olur.

4:43 Çağıranınızın gerçekten ihtiyaç duyduğu sonucu ölçün. Şimdi o kısayola gelelim. Bir Python fonksiyonunuz var ve bir diziyi kabul etmesini istiyorsunuz. Vectorize adlı bir sarmalayıcı, eksik performans düğmesi gibi geliyor. Dokümantasyonunda önemli bir cümle sizi bekliyor.

np.vectorize aslında neyi yürütüyor?

4:56 NumPy, vectorize sarmalayıcısının öncelikle kolaylık için sağlandığını belirtir. Uygulaması esasen bir for döngüsüdür. Sarmalayıcı yığınları kabul eder, ancak ardışık öğeler için Python fonksiyonunuzu çağırmaya devam eder. Arayüz kısaldı. Yürütme sınırı meşgul kaldı. Aynı değerlerin Python geri çağrısı aracılığıyla geri geldiğini izleyin. Hazır dizilerle, bu sürüm yaklaşık seksen yedi milisaniye sürdü. Anlama becerimizden daha yavaştı.

5:18 Faydalı bir yayın sarmalayıcısı, kaldırmaya çalıştığınız öğe başına tam işi koruyabilir. Bir yığın arayüzünün arkasındaki uygulamayı kontrol edin, uyumlu verileri faydalı biçiminde tutun ve karşılaştırmaya dönüşümü dahil edin. Yerel, geri çağrı ve derlenmiş döngüler, çağıranın açısından benzer görünebilir. Vectorize adı, kronometrenizin hiç imzalamadığı bir söz verdi. Kolaylık ihtiyacınız olduğunda onu saklayın. Performans için, çalışan döngüyü kontrol edin.

Kodunuzda neyi değiştirmelisiniz?

5:41 Benim kararım, ölçülen sayısal sıcak bir yolu toplu işlemek için SHIP IT. Zaten iyi çalıştıklarında sıradan döngüleri koruyun. İşin nerede olduğunu ve bir sonraki çağıranın neye ihtiyacı olduğunu kontrol edin. Abone olun, zili çalın ve farklı bir şekilde damgalayıp damgalamayacağınızı yorumlar bölümünde bana bildirin. Ve bugünün farkı bu. Ben Axrisi'den Niko. Sorumlulukla birleştirin.

Kaynaklar

  1. Universal functions (ufunc) basics — NumPy 2.2NumPy
  2. The N-dimensional array — NumPy 2.2NumPy
  3. numpy.vectorize — convenience and performance notesNumPy
  4. CPU/SIMD optimizations — NumPy 2.2NumPy
  5. dis — Disassembler for Python bytecodePython Software Foundation
  6. CPython 3.10.12 list representationCPython contributors
  7. The limits of Python vectorization as a performance techniqueItamar Turner-Trauring / Python⇒Speed
  8. Performance TipsNumba
  9. Basics of CuPyCuPy

İlgili videolar