C kütüphanesini Python'a mı sarmak: C, Cython veya ctypes?


284

Bir Python uygulamasından bir C kütüphanesini çağırmak istiyorum. Tüm API'yı, yalnızca benim durumumla ilgili olan işlevleri ve veri türlerini sarmak istemiyorum. Gördüğüm gibi üç seçeneğim var:

  1. C de gerçek bir genişletme modülü oluşturun.
  2. İlgili parçaları C kitaplığından Python'a göstermek için Cython'u kullanın .
  3. Python'da her şeyi ctypesharici kitaplıkla iletişim kurmak için yapın.

2) veya 3) daha iyi bir seçim olup olmadığından emin değilim. 3) avantajı ctypes, standart kütüphanenin bir parçasıdır ve ortaya çıkan kod saf Python olacaktır - ancak bu avantajın ne kadar büyük olduğundan emin değilim.

Her iki seçimde de daha fazla avantaj / dezavantaj var mı? Hangi yaklaşımı öneriyorsunuz?


Edit: Tüm cevaplarınız için teşekkürler, onlar benzer bir şey yapmak isteyen herkes için iyi bir kaynak sağlar. Karar, elbette, hala tek bir dava için verilecek - kimse "Bu doğru şey" cevabı. Kendi durumum için, muhtemelen ctypes ile gideceğim, ama aynı zamanda başka bir projede Cython'u denemeyi dört gözle bekliyorum.

Tek bir doğru cevap olmadığı için, bir tanesini kabul etmek biraz keyfi; FypeBird'in cevabını seçtim çünkü ctypes hakkında iyi bir fikir veriyor ve şu anda da en yüksek oy alan cevap. Ancak, iyi bir genel bakış için tüm cevapları okumanızı öneririm.

Tekrar teşekkürler.


3
Bir dereceye kadar, ilgili spesifik uygulama (kütüphanenin yaptığı) yaklaşım seçimini etkileyebilir. Ctypes'i çeşitli hardare parçaları (örneğin osiloskoplar) için satıcı tarafından sağlanan DLL'lerle konuşmak için oldukça başarılı bir şekilde kullandık, ancak Cython veya SWIG'e karşı ek yük nedeniyle sayısal bir işlem kütüphanesiyle konuşmak için önce ctypes seçmem gerekmiyordu.
Peter Hansen

1
Şimdi aradığın şeye sahipsin. Dört farklı cevap (biri SWIG'yi de buldu). Yani 3 yerine 4 seçeneğiniz var.
Luka Rahne

@ralu Ben de öyle düşündüm :-) Ama cidden, ben bir pro / con tablo veya "İşte yapmanız gerekenler" diyerek tek bir cevap beklemiyordum (veya istemiyordu). Karar verme ile ilgili herhangi bir soru en iyi, nedenlerini belirterek olası her seçimin "taraftarları" ile yanıtlanır. Topluluk oylaması daha sonra kendi çalışmalarımda olduğu gibi kendi görevini yerine getirir (argümanlara bakmak, bunları benim durumuma uygulamak, sağlanan kaynakları okumak, vb.). Uzun lafın kısası: Burada bazı iyi cevaplar var.
balpha

Peki hangi yaklaşımı uygulayacaksınız? :)
FogleBird

1
Bildiğim kadarıyla (eğer yanılıyorsam beni düzeltin), Cython daha fazla gelişme gösteren Pyrex'in bir çatalıydı ve Pyrex'i oldukça eski yapıyor.
balpha

Yanıtlar:


115

ctypes hızlı bir şekilde halletmek için en iyi bahistir ve hala Python yazarken çalışmak bir zevktir!

Kısa bir süre önce ctypes kullanarak bir USB çipi ile iletişim kurmak için bir FTDI sürücüsünü paketledim ve harikaydı. Her şeyi bir iş gününden daha kısa sürede yaptım ve çalıştım. (Sadece ihtiyacımız olan fonksiyonları, yaklaşık 15 fonksiyonu uyguladım).

Daha önce aynı amaçla üçüncü taraf bir modül olan PyUSB kullanıyorduk . PyUSB gerçek bir C / Python genişletme modülüdür. Ancak PyUSB, okuma / yazma engelleme yaparken GIL'i serbest bırakmıyordu, bu da bizim için sorun yaratıyor. Bu yüzden kendi modülümüzü yerel fonksiyonları çağırırken GIL'i serbest bırakan ctypes kullanarak yazdım.

Unutulmaması gereken bir nokta, ctypes'in #definekullandığınız kütüphanedeki sabitler ve şeyler hakkında bilgi sahibi olmayacağı , sadece işlevler olduğu için bu sabitleri kendi kodunuzda yeniden tanımlamanız gerekecek.

Kodun nasıl göründüğüne bir örnek (çok sayıda parçalanmış, sadece bunun özünü göstermeye çalışıyor):

from ctypes import *

d2xx = WinDLL('ftd2xx')

OK = 0
INVALID_HANDLE = 1
DEVICE_NOT_FOUND = 2
DEVICE_NOT_OPENED = 3

...

def openEx(serial):
    serial = create_string_buffer(serial)
    handle = c_int()
    if d2xx.FT_OpenEx(serial, OPEN_BY_SERIAL_NUMBER, byref(handle)) == OK:
        return Handle(handle.value)
    raise D2XXException

class Handle(object):
    def __init__(self, handle):
        self.handle = handle
    ...
    def read(self, bytes):
        buffer = create_string_buffer(bytes)
        count = c_int()
        if d2xx.FT_Read(self.handle, buffer, bytes, byref(count)) == OK:
            return buffer.raw[:count.value]
        raise D2XXException
    def write(self, data):
        buffer = create_string_buffer(data)
        count = c_int()
        bytes = len(data)
        if d2xx.FT_Write(self.handle, buffer, bytes, byref(count)) == OK:
            return count.value
        raise D2XXException

Birisi çeşitli seçenekler üzerinde bazı kriterler yaptı .

Sınıflar / şablonlar / vb bir sürü ile bir C ++ kitaplığı sarmak zorunda kalırsam daha tereddüt olabilir. Ancak ctypes yapılarla iyi çalışır ve hatta Python'a geri çağrı yapabilir .


5
Ctypes için övgülere katılmak, ancak bir (belgesiz) konuya dikkat edin: ctypes çatallanmayı desteklemez. Ctypes kullanan bir işlemden çatallanırsanız ve hem üst hem de alt işlemler ctypes kullanmaya devam ederse, paylaşılan belleği kullanarak ctypes ile ilgili olan kötü bir hataya rastlayacaksınız.
Oren Shemesh

1
@OrenShemesh Bu konuda bana işaret edebileceğiniz başka bir okuma var mı? Şu anda üzerinde çalıştığım bir projeyle güvende olabileceğimi düşünüyorum, çünkü sadece üst sürecin ctypes(için pyinotify) kullandığına inanıyorum , ancak sorunu daha iyi anlamak istiyorum.
zigg

Bu pasaj bana çok yardımcı oluyor One thing to note is that ctypes won't know about #define constants and stuff in the library you're using, only the functions, so you'll have to redefine those constants in your own code.Yani, orada var olan sabitleri tanımlamak zorunda winioctl.h....
swdev

performansa ne dersin? ctypesdarboğaz Python'dan C'ye arayüz olduğundan c-uzantısından çok daha yavaş
TomSawyer

154

Uyarı: Bir Cython çekirdeği geliştiricisinin görüşü ileride.

Cython'u neredeyse her zaman ctypes üzerinden tavsiye ederim. Nedeni çok daha sorunsuz bir yükseltme yolu olmasıdır. Ctypes kullanıyorsanız, ilk başta birçok şey basit olacak ve derleme olmadan, bağımlılıklar ve tüm bunları yapmadan FFI kodunuzu düz Python'a yazmak kesinlikle harika. Bununla birlikte, bir noktada, C kütüphanenize bir döngüde veya daha uzun bir süre birbirine bağımlı çağrılarda çok fazla çağrı yapmanız gerektiğini ve bunu hızlandırmak istediğinizi neredeyse kesin olarak göreceksiniz. İşte bunu ctypes ile yapamayacağınızı fark edeceğiniz nokta. Veya geri arama işlevlerine ihtiyacınız olduğunda ve Python geri arama kodunuzun bir darboğaz haline geldiğini fark ettiğinizde, bunu hızlandırmak ve / veya C'ye taşımak istersiniz. Yine, bunu ctypes ile yapamazsınız.

Cython, OTOH ile, sarma ve arama kodunu istediğiniz kadar ince veya kalın yapmak tamamen ücretsizdir. Normal Python kodundan C kodunuza basit çağrılarla başlayabilirsiniz ve Cython bunları ek çağrı yükü olmadan ve Python parametreleri için son derece düşük bir dönüşüm yükü ile yerel C çağrılarına dönüştürür. C kitaplığınıza çok fazla pahalı arama yaptığınız bir noktada daha fazla performansa ihtiyacınız olduğunu fark ettiğinizde, çevredeki Python kodunuzu statik türlerle açıklamaya başlayabilir ve Cython'un bunu doğrudan sizin için C'ye optimize etmesine izin verebilirsiniz. Veya aramalardan kaçınmak ve döngülerinizi algoritmik olarak özelleştirmek ve sıkmak için C kodunuzun bazı bölümlerini Cython'da yeniden yazmaya başlayabilirsiniz. Hızlı bir geri aramaya ihtiyacınız varsa, sadece uygun imzayla bir işlev yazın ve doğrudan C geri arama kaydına iletin. Yine, havai değil ve size düz C arama performansı sağlar. Ve kodunuzu Cython'da gerçekten yeterince hızlı alamadığınız daha az olası bir durumda, yine de C (veya C ++ veya Fortran) 'da gerçekten kritik kısımlarını yeniden yazmayı ve doğal ve doğal olarak Cython kodunuzdan çağırabilirsiniz. Ama sonra, bu gerçekten tek seçenek yerine son çare haline geliyor.

Yani, ctypes basit şeyler yapmak ve hızlı bir şekilde bir şeyler yapmak güzel. Ancak, işler büyümeye başlar başlamaz, büyük olasılıkla Cython'u en başından daha iyi kullandığınızı fark ettiğiniz noktaya geleceksiniz.


4
+1 bunlar iyi puan, çok teşekkürler! Rağmen sadece darboğaz parçaları Cython taşımak gerçekten bu kadar ek yük olduğunu. Ancak katılıyorum, herhangi bir performans sorunu bekliyorsanız, Cython'u en başından da kullanabilirsiniz.
balpha

Bu hem C hem de Python ile deneyimli programcılar için hala geçerli mi? Bu durumda, C döngülerinin (SIMD) vektörleştirilmesi bazen daha basit olduğu için Python / ctypes'in daha iyi bir seçim olduğu iddia edilebilir. Ancak, bunun dışında herhangi bir Cython dezavantajı düşünemiyorum.
Alex van Houten

Cevap için teşekkürler! Cython ile ilgili sorun yaşadığım bir şey, derleme işlemini doğru yapmak (ancak daha önce hiç Python modülü yazmama gerek yok) - daha önce derlemeliyim veya sdist ve benzer sorulara Cython kaynak dosyalarını dahil etmeliyim. Kimsenin benzer sorunları / şüpheleri olması durumunda bu konuda bir blog yazısı yazdım: martinsosic.com/development/2016/02/08/…
Martinsos

Cevap için teşekkürler! Cython'u kullanmamın bir dezavantajı, operatör aşırı yüklemesinin tam olarak uygulanmamasıdır (örn. __radd__). Sınıfınızın yerleşik türlerle (ör. intVe float) etkileşime girmesini planladığınızda bu özellikle can sıkıcıdır . Ayrıca, cython'daki sihirli yöntemler genel olarak biraz buggy.
Monolith

100

Cython kendi içinde oldukça iyi bir araçtır, öğrenmeye değer ve şaşırtıcı bir şekilde Python sözdizimine yakındır. Numpy ile herhangi bir bilimsel hesaplama yaparsanız, Cython hızlı matris işlemleri için Numpy ile entegre olduğu için gitmenin yoludur.

Cython, Python dilinin bir üst kümesidir. Geçerli herhangi bir Python dosyasını atabilirsiniz ve geçerli bir C programı çıkarır. Bu durumda, Cython sadece Python çağrılarını temeldeki CPython API ile eşler. Kodunuz artık yorumlanmadığından, bu belki de% 50'lik bir hızlanma ile sonuçlanır.

Bazı optimizasyonlar elde etmek için Cython'a kodunuz hakkında tür bildirimleri gibi ek bilgiler vermeye başlamanız gerekir. Eğer yeterince söylerseniz, kodu saf C'ye kadar kaynatın. Yani, Python'daki bir for döngüsü C'deki bir for döngüsü haline gelir. Burada devasa hız kazançları göreceksiniz. Harici C programlarına buradan da bağlanabilirsiniz.

Cython kodunu kullanmak da inanılmaz derecede kolaydır. Kılavuzun kulağa zor geldiğini düşündüm. Kelimenin tam anlamıyla:

$ cython mymodule.pyx
$ gcc [some arguments here] mymodule.c -o mymodule.so

ve sonra import mymodulePython kodunuzu girebilir ve tamamen C'ye derlediğini unutabilirsiniz.

Her durumda, Cython'u kurmak ve kullanmaya başlamak çok kolay olduğu için, ihtiyaçlarınıza uygun olup olmadığını görmek için denemenizi öneririz. Aradığınız araç olmadığı ortaya çıkarsa, bu bir atık olmayacaktır.


1
Sorun değil. Cython ile ilgili güzel bir şey, sadece neye ihtiyacınız olduğunu öğrenebilmenizdir. Sadece mütevazı bir gelişme istiyorsanız, tek yapmanız gereken Python dosyalarınızı derlemek ve işiniz bitti.
carl

18
"Geçerli herhangi bir Python dosyasını atabilir ve geçerli bir C programı çıkaracaktır." <- Pek değil, bazı sınırlamalar var: docs.cython.org/src/userguide/limitations.html Çoğu kullanım vakası için sorun değil, ancak tam olmak istedim.
Randy Syring

7
Her sayfanın sayısı gittikçe azalıyor, bu sayfada artık "sorunların çoğu 0.15'te çözüldü" yazıyor.
Henry Gomersall

3
Eklemek için, cython kodunu içe aktarmanın daha kolay bir yolu var: cython kodunuzu bir mymod.pyxmodül olarak yazın import pyximport; pyximport.install(); import mymodve yapın ve derleme sahne arkasında gerçekleşir.
Kaushik Ghose

3
@kaushik Daha da basit olan pypi.python.org/pypi/runcython . Sadece kullan runcython mymodule.pyx. Pyximport'un aksine, daha zorlu bağlantı görevleri için kullanabilirsiniz. Tek uyarı, bunun için 20 satır bash yazan ve taraflı olabileceğim.
RussellStewart

42

Bir Python uygulamasından bir C kütüphanesini çağırmak için, ctypes için yeni bir alternatif olan cffi de vardır . FFI için yeni bir görünüm getiriyor:

  • problemi büyüleyici ve temiz bir şekilde ele alır ( kiplerin aksine )
  • Python olmayan kodların yazılmasını gerektirmez ( SWIG, Cython , ... gibi)

kesinlikle OP'nin istediği gibi sarma için gidilecek yol . cython onları sıcak döngüler yazmak için harika görünüyor, ancak arayüzler için cffi sadece ctypes'den düz bir yükseltmedir.
uçan koyun

21

Oraya başka bir tane daha atacağım: SWIG

Öğrenmesi kolaydır, birçok şeyi doğru yapar ve daha birçok dili destekler, böylece öğrenmeye harcanan zaman oldukça faydalı olabilir.

SWIG kullanıyorsanız, yeni bir python genişletme modülü oluşturuyorsunuz, ancak SWIG ağır kaldırma işlemlerinin çoğunu sizin için yapıyor.


18

Şahsen, C'ye bir genişletme modülü yazardım. Python C uzantıları tarafından korkutmayın - yazmak hiç de zor değil. Dokümantasyon çok net ve yardımsever. Python'da ilk kez bir C uzantısı yazdığımda, nasıl yazacağımı anlamanın yaklaşık bir saat sürdüğünü düşünüyorum - çok fazla zaman değil.


Bir C kütüphanesini sarma. Aslında kodu burada bulabilirsiniz: github.com/mdippery/lehmer
mipadi

1
@forivall: Kod gerçekten o kadar kullanışlı değildi ve orada daha iyi rasgele sayı üreteçleri var. Yalnızca bilgisayarımda bir yedek var.
mipadi

2
Kabul. Python'un C-API'si göründüğü kadar korkutucu değil (C'yi bildiğiniz varsayılarak). Bununla birlikte, python ve kütüphaneler, kaynaklar ve geliştiriciler rezervuarından farklı olarak, C'de uzantılar yazarken temel olarak kendinizsiniz. Muhtemelen tek dezavantajı (genellikle C ile yazma ile gelenler dışında).
Noob Saibot

1
mipadi: Peki, ama Python 2.x ve 3.x arasında farklılık gösterirler, bu nedenle uzantınızı yazmak için Cython kullanmak, Cython'un tüm ayrıntıları bulmasını ve ardından Python 2.x için oluşturulan C kodunu derlemesini veya 3.x gerektiği gibi.
0xC0000022L

2
mipadi, github bağlantısının öldüğü ve archive.org'da görünmüyor gibi görünüyor, bir yedeğiniz var mı?
jrh

11

ctypes zaten başa çıkmak için derlenmiş bir kütüphane blob (OS kütüphaneleri gibi) olduğunda harika. Arama yükü şiddetlidir, ancak kütüphaneye çok fazla çağrı yapacaksanız ve yine de C kodunu yazacaksınız (veya en azından derleyin), cython . Çok daha fazla iş değil ve ortaya çıkan pyd dosyasını kullanmak çok daha hızlı ve daha pitonik olacak.

Şahsen python kodunun hızlı hızlandırmaları için cython kullanma eğilimindeyim (döngüler ve tamsayı karşılaştırmaları cython'un özellikle parladığı iki alandır) ve diğer kütüphanelerin daha fazla dahil olduğu kod / sarma olduğunda, Boost.Python'a döneceğim . Python kurmak için titiz olabilir, ancak bir kez çalıştıktan sonra, C / C ++ kodunu sarmayı kolaylaştırır.

cython da ( SciPy 2009 işlemlerinden öğrendim) numpy sarma harika , ama numpy kullanmadım, bu yüzden bu konuda yorum yapamam.


11

Tanımlı bir API'ye sahip bir kitaplığınız varsa, sanırım ctypes , en iyi seçenek , çünkü sadece küçük bir başlatma yapmanız ve daha sonra az ya da çok kütüphaneyi alıştığınız şekilde çağırmanız gerekir.

Cython veya C (bir çok zor değil) bir genişletme modülü oluşturmak, örneğin bu kütüphaneyi çağırmak ve bazı karmaşık, zaman alıcı görevleri yapmak ve sonra sonucu Python geçirerek yeni kod gerektiğinde daha yararlı olduğunu düşünüyorum.

Basit programlar için başka bir yaklaşım, doğrudan standart çıktıya çıktı veren ve alt işlem modülü ile çağıran farklı bir işlem (harici olarak derlenmiş) doğrudan yapmaktır. Bazen en kolay yaklaşım budur.

Örneğin, bu şekilde daha fazla veya daha az çalışan bir konsol C programı yaparsanız

$miCcode 10
Result: 12345678

Python'dan arayabilirsiniz

>>> import subprocess
>>> p = subprocess.Popen(['miCcode', '10'], shell=True, stdout=subprocess.PIPE)
>>> std_out, std_err = p.communicate()
>>> print std_out
Result: 12345678

Küçük bir dize oluşturmayla sonucu istediğiniz şekilde alabilirsiniz. Standart hata çıktısını da yakalayabilirsiniz, bu nedenle oldukça esnektir.


Bu cevapla ilgili yanlış bir şey olmasa da, kodun başkaları tarafından erişilmesi için dikkatli olması gerekir, çünkü alt işlem çağrısı shell=Truebir kullanıcı gerçekten bir kabuk aldığında kolayca bir tür sömürüye neden olabilir. Geliştirici tek kullanıcı olduğunda iyi, ancak dünyada böyle bir şey bekleyen bir sürü can sıkıcı piç var.
Ben

7

Beni cython değil ctypes kullanmamı sağlayan ve diğer cevaplarda belirtilmeyen bir konu var.

Ctypes kullanmak sonuç, kullandığınız derleyiciye bağlı değildir. Yerel paylaşılan kitaplığa derlenebilecek az çok dil kullanarak bir kitaplık yazabilirsiniz. Hangi sistem, hangi dil ve hangi derleyici önemli değil. Ancak Cython altyapı ile sınırlıdır. Örneğin, Windows'ta intel derleyicisini kullanmak istiyorsanız, cython'un çalışması çok daha zordur: derleyiciyi cython'a "açıklamalısınız", bu tam derleyiciyle bir şeyi yeniden derlemelisiniz, vb. Bu, taşınabilirliği önemli ölçüde sınırlar.


4

Windows'u hedefliyorsanız ve bazı tescilli C ++ kitaplıklarını sarmayı seçiyorsanız, yakında msvcrt***.dll(Visual C ++ Çalışma Zamanı) farklı sürümlerinin biraz uyumsuz olduğunu keşfedebilirsiniz .

Bu, Cythonsonuç (Python 2.7) veya (Python 3.x)wrapper.pyd ile bağlantılı olduğu için kullanamayabileceğiniz anlamına gelir . Kaydırdığınız kitaplık, çalışma zamanının farklı sürümüne bağlıysa, şansınız kalmaz.msvcr90.dll msvcr100.dll

Sonra işler işe yaraması için C ++ kütüphaneleri için C sarmalayıcıları oluşturmanız gerekir, bu sarmalayıcı dll msvcrt***.dllC ++ kitaplığı ile aynı sürümüne bağlantı . Ve sonra ctypesçalışma zamanında dinamik olarak el haddelenmiş sarıcı dll yüklemek için kullanın .

Bu nedenle, aşağıdaki makalede ayrıntılı olarak açıklanan birçok küçük ayrıntı var:

"Güzel Yerli Kütüphaneler (Python'da) ": http://lucumr.pocoo.org/2013/8/18/beautiful-native-libraries/


Bu makalede, Microsoft derleyicilerinin uyumluluğu ile gündeme getirdiğiniz sorunlarla ilgisi yoktur. Cython uzantılarının Windows üzerinde çalışmasını sağlamak çok zor değil. MinGW'yi hemen hemen her şey için kullanabildim. İyi bir Python dağıtımı yardımcı olur.
IanH

2
Windows'ta olası bir sorundan bahsettiğiniz için +1 (şu anda da yaşıyorum ...). @IanH genel olarak pencereler hakkında daha az, ancak python dağıtımınızla eşleşmeyen belirli bir üçüncü taraf lib ile sıkışıp kalmanız bir karışıklıktır.
sebastian


2

Bu eski bir soru olduğunu biliyorum ama böyle şeyler aradığınızda bu şey google'da ortaya çıkıyor ctypes vs cythonve buradaki cevapların çoğu zaten yetkin olanlar tarafından yazılıyor cythonveya cbunları öğrenmek için yatırım yapmak için gereken gerçek zamanı yansıtmayabilir. çözümünüzü uygulamak için. Ben ikisinde de tam bir acemiyim. Daha cythonönce hiç dokunmadım ve çok az deneyime sahibim c/c++.

Son iki gündür, kodumun ağır bir bölümünü python'dan daha düşük bir seviyeye devretmenin bir yolunu arıyordum. Ben hem kodumu uygulanan ctypesve Cythontemelde iki basit fonksiyonları oluşuyordu.

İşlenmesi gereken büyük bir dize listesi vardı . Uyarı listve string. Her iki tür de türlere mükemmel şekilde karşılık gelmez c, çünkü python dizeleri varsayılan olarak unicode ve cdizeler değildir. Python'daki listeler c.

İşte benim kararım. Kullanın cython. Python'a daha akıcı bir şekilde entegre olur ve genel olarak çalışmak daha kolaydır. Bir şeyler ters gittiğinde ctypessadece segfault atar, en azından cythonmümkün olduğunda bir yığın izlemesi ile derleme uyarıları verir ve geçerli bir python nesnesini kolayca döndürebilirsiniz cython.

Aynı işlevi uygulamak için her ikisine de ne kadar zaman ayırmam gerektiğine dair ayrıntılı bir hesap. Bu arada çok az C / C ++ programlama yaptım:

  • ctypes:

    • Unicode dizeleri listemi ac uyumlu tipe nasıl dönüştüreceğimizi araştırırken yaklaşık 2 saat.
    • Ac işlevinden düzgün bir dize döndürmek için yaklaşık bir saat. Burada fonksiyonları yazdıktan sonra aslında SO'ya kendi çözümümü sağladım .
    • Kodu c'ye yazmak için yaklaşık yarım saat, dinamik bir kütüphaneye derleyin.
    • 10 dakika ckodun çalışıp çalışmadığını kontrol etmek için python'a bir test kodu yazmak .
    • Yaklaşık bir saat boyunca bazı testler yapın ve ckodu yeniden düzenleyin .
    • Sonra ckodu gerçek kod tabanına taktım ve işleyicisi varsayılan olarak seçilemediğinden modülle ctypesiyi oynatılmadığını gördüm multiprocessing.
    • Yaklaşık 20 dakika kodumu multiprocessingmodül kullanmayacak şekilde yeniden düzenledim ve tekrar denedim.
    • Sonra benim ckod ikinci işlev test kodumu geçti rağmen benim kod tabanı segfaults oluşturdu. Eh, bu muhtemelen kenar vakaları ile iyi kontrol değil benim hatam, hızlı bir çözüm arıyordu.
    • Yaklaşık 40 dakika boyunca bu segfaultların olası nedenlerini belirlemeye çalıştım.
    • İşlevlerimi iki kütüphaneye ayırdım ve tekrar denedim. İkinci görevim için hala segfaultlar vardı.
    • İkinci işlevi bırakmaya ve ckodun sadece ilk işlevini kullanmaya karar verdim ve bunu kullanan python döngüsünün ikinci veya üçüncü yinelemesinde, UnicodeErrorkodlamayı ve her şeyi çözdüğüm halde bir konumda bir bayt kod çözmeme explicitely.

Bu noktada bir alternatif aramaya karar verdim ve şunlara bakmaya karar verdim cython:

  • Cython
    • 10 dakika cython merhaba dünya okuma .
    • 15 dakika yerine yerine cython kullanmak için SO kontrol .setuptoolsdistutils
    • Cython türleri ve python türleri üzerinde 10 dakikalık okuma . Statik yazım için yerleşik python türlerinin çoğunu kullanabileceğimi öğrendim.
    • 15 dakika python kodumu cython türleri ile yeniden.
    • 10 dakika setup.pybenim kod temeli derlenmiş modülü kullanmak için değiştirme .
    • Modül doğrudan multiprocessingkod temeli sürümüne takıldı. İşe yarıyor.

Kayıt için, elbette, yatırımımın kesin zamanlamalarını ölçmedim. Ctypes'le uğraşırken gereken zihinsel çaba nedeniyle zaman algımın biraz dikkatli olması çok iyi olabilir. Ama başa hissi iletmek gerekir cythonvectypes

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.