แปลงโปรแกรม Python เป็นรหัส C / C ++ หรือไม่ [ปิด]


149

เป็นไปได้ไหมที่จะแปลงโปรแกรม Python เป็น C / C ++

ฉันต้องใช้อัลกอริธึมสองสามอย่างและฉันไม่แน่ใจว่าช่องว่างของประสิทธิภาพนั้นใหญ่พอที่จะพิสูจน์ความเจ็บปวดทั้งหมดที่ฉันได้รับเมื่อทำใน C / C ++ (ซึ่งฉันไม่ค่อยเก่ง) ฉันคิดถึงการเขียนอัลกอริธึมง่ายๆและเปรียบเทียบกับโซลูชันที่แปลงแล้ว ถ้าอย่างเดียวนั้นเร็วกว่ารุ่น Python อย่างมากฉันจะไม่มีทางเลือกอื่นนอกจากทำใน C / C ++


32
ให้จำไว้ว่าการชะลอตัว 50x หรือ 100x นั้นยังไม่สามารถทำได้หากการคำนวณเสร็จสิ้นในไม่กี่วินาทีใน Python และไม่เป็นจริงเมื่อคุณทำ I / O จำนวนมากหรือมีอัลกอริธึมที่น่ากลัว แทนที่จะถามว่า "ไพ ธ อนช้าแค่ไหน" คุณควรถามว่า "Python เร็วพอหรือยัง" (และเป็นไปได้มากที่สุดโดยสุจริต) - ที่เร็วกว่าการเปรียบเทียบหรือถามที่นี่

1
การใช้อัลกอริทึมในไพ ธ อนนั้นรวดเร็วและตรงไปตรงมา ... คุณเพียงแค่ต้องทำมันแล้วตรวจสอบว่ามันเร็วพอหรือไม่ เวลาส่วนใหญ่คุณสามารถปรับแต่งอัลกอริทึมให้ทำงานเร็วขึ้นโดยใช้โครงสร้างข้อมูลที่แตกต่างกัน (dict / sets แทนที่จะเป็น list ... ) หรือการทำงานที่แตกต่างกัน การเพิ่มประสิทธิภาพต่อไปควรเกิดขึ้นหลังจากที่คุณได้ใช้งานแบบร่างแรกของอัลกอริทึมแล้วและทำการเปรียบเทียบ / ทำโปรไฟล์
Bakuriu

@delnan: ในกรณีของฉันมันคือทั้งหมดที่เกี่ยวกับเวลาในการคำนวณ หากตัวแปร C ต้องการเวลาน้อยกว่า x ชั่วโมงฉันจะลงทุนในช่วงเวลานั้นเพื่อให้อัลกอริทึมทำงานได้นานขึ้นอีกครั้ง ฉันแค่ต้องการค้นหา (โดยประมาณ) ว่า Python จะช้าลงเพียงใด - ถ้าใช้เวลาสองสามชั่วโมงฉันจะไม่ใช้ภาษาที่ฉันไม่พอใจ (คุณสามารถทำลายวิธีแก้ปัญหาที่ดีที่สุดสำหรับการใช้งานที่ไม่ดี: P)
CrazyFlyingCloseline

@ delnan ถูกต้องเกี่ยวกับ Python อาจจะเร็วพอสำหรับหลาย ๆ อย่าง แม้ว่าจะช้าลงความง่ายในการพัฒนาการบำรุงรักษาและการปรับปรุงในอนาคตเป็นปัจจัยสำคัญที่ต้องพิจารณา
martineau

"x ชั่วโมง" มันใหญ่แค่ไหน? คุณเคยเปรียบเทียบการใช้งานหรือไม่? คุณมีการวัดหรือไม่? คุณทำโปรไฟล์การนำไปปฏิบัติหรือไม่? หรือคุณกำลังพยายามเพิ่มประสิทธิภาพการแก้ปัญหาก่อนกำหนด?
S.Lott

คำตอบ:


115

ใช่. ดูCython มันทำได้แค่นั้น: แปลง Python เป็น C เพื่อเพิ่มความเร็ว


6
แน่นอนว่าจะไม่ช่วยอะไรคุณจนกว่าคุณจะเพิ่มการcdefประกาศจำนวนมากและดังนั้นจึงแนะนำการพิมพ์แบบสแตติกPyObject *สิ่ง ) และมันจะไม่เร็วเท่า C ธรรมดาเพราะมันมักจะเชื่อมต่อกับ Python (100% หรือมากกว่านั้นเท่านั้นสำหรับรหัสตัวเลขธรรมดาที่ไม่ได้เชื่อมต่อกับ Python เลยในเวลาส่วนใหญ่!) แต่นอกเหนือจากนั้นใช่แล้วคุณสามารถเพิ่มความเร็วได้เร็วขึ้น

7
@delnan: อันที่จริงมันช่วยอะไรคุณได้บ้าง รหัสไพ ธ อนบริสุทธิ์ส่วนใหญ่จะเร็วขึ้นหลังจากรวบรวม แต่ใช่ด้วย cdefs และการพิมพ์คงที่คุณเริ่มเห็นความแตกต่าง และการเชื่อมต่อกับ Python คุณจะได้รับในทุกกรณีที่คุณใช้ C จาก Python
Lennart Regebro

136

หากตัวแปร C ต้องการเวลาน้อยกว่า x ชั่วโมงฉันจะลงทุนเวลานั้นเพื่อให้อัลกอริทึมทำงานได้นานขึ้น / อีกครั้ง

"ลงทุน" ไม่ใช่คำที่เหมาะสมที่นี่

  1. สร้างการใช้งานใน Python คุณจะดำเนินการให้เสร็จก่อนที่จะเสร็จสิ้นเวอร์ชัน C

  2. วัดประสิทธิภาพด้วย Python Profiler แก้ไขปัญหาที่คุณพบ เปลี่ยนโครงสร้างข้อมูลและอัลกอริทึมตามความจำเป็นเพื่อดำเนินการอย่างถูกต้อง คุณจะจบเรื่องนี้ให้เสร็จก่อนที่คุณจะจบเวอร์ชั่นแรกในซี

  3. ถ้ามันยังช้าเกินไปให้แปล Python ที่ออกแบบมาอย่างดีและสร้างด้วยความระมัดระวังเป็น C

    เนื่องจากวิธีการเข้าใจถึงปัญหาหลังเหตุการณ์การทำรุ่นที่สองจาก Python ที่มีอยู่ (ด้วยการทดสอบหน่วยที่มีอยู่และด้วยข้อมูลการทำโปรไฟล์ที่มีอยู่) จะยังเร็วกว่าการพยายามทำรหัส C ตั้งแต่เริ่มต้น

คำพูดนี้มีความสำคัญ

กฎของทอมป์สันสำหรับผู้สร้างกล้องโทรทรรศน์
เป็นครั้งแรกมันเร็วกว่าในการสร้างกระจกสี่นิ้วและจากนั้นจะเป็นกระจกหกนิ้วมากกว่าที่จะสร้างกระจกหกนิ้ว


สถาบันBill McKeenan Wang


15
ฉันไม่เห็นว่าสิ่งนี้จะตอบคำถามได้อย่างไร
Audrius Meskauskas

29

Shed Skinคือ "คอมไพเลอร์ Python-to-C ++" (จำกัด )


3
+1 ข้อดีอย่างหนึ่งของ Shed Skin คือการอนุมานประเภท : หากเป็นไปได้ที่จะเดาชนิดตัวแปรจากโฟลว์ของโปรแกรมการหลีกเลี่ยงการตรวจสอบประเภทแบบไดนามิกจะหลีกเลี่ยง โดยทั่วไปแล้วจะนำไปสู่รหัส C ++ ที่สั้นลงซึ่งเป็นไปได้ที่จะอ่านและคอมไพล์โปรแกรมที่เร็วขึ้น
Kyss Tao

1
นอกจากนี้ยังมีPython → 11l → C ++ transpilerซึ่งเป็นตัวคอมไพเลอร์ Python ที่ถูก จำกัด ไปยัง C ++ แต่รองรับคุณสมบัติ Python บางตัวที่ไม่รองรับ Shed Skin (เช่นฟังก์ชัน / การปิดซ้อน)
TAV

17

เพิ่งเจอเครื่องมือใหม่นี้ในข่าวแฮ็กเกอร์

จากหน้าของพวกเขา - "Nuitka เป็นการแทนที่ที่ดีสำหรับ Python interpreter และคอมไพล์ทุกตัวที่ CPython 2.6, 2.7, 3.2 และ 3.3 เสนอมันแปล Python เป็นโปรแกรม C ++ ที่ใช้" libpython "เพื่อดำเนินการในลักษณะเดียวกับ CPython ทำในวิธีที่เข้ากันได้ดีมาก "


โครงการนี้มีความเป็นผู้ใหญ่มากกว่าตัวเลือกอื่น ๆ ที่คล้ายคลึงกัน เป็นเรื่องตลกที่มันสร้างไบนารีพร้อมกับ.exeส่วนขยายบน OSX แม้ว่าจะเป็น OSX Mach-O ปกติที่สามารถใช้งานได้ ดูเหมือนว่ามันอาจจะมีการเปลี่ยนที่ดีสำหรับpyinstaller, py2exe, py2appฯลฯ--recurse-***ธงที่มีความสำคัญที่จะตั้งอย่างถูกต้องว่า
ccpizza

Nuitka นั้นยอดเยี่ยม แต่โค้ด C / C ++ ที่สร้างขึ้นนั้นใช้ PyObject ซึ่งเชื่อมโยงกับการใช้งาน CPython-C-code-implementation มันไม่ได้ผลิตรหัส C สำนวน
Make42

8

ตัวเลือกอื่น - การแปลงเป็น C ++ นอกเหนือจากShed Skin - คือPythran Pythran

ในการอ้างถึงPython ประสิทธิภาพสูงโดย Micha Gorelick และ Ian Ozsvald :

Pythran เป็นคอมไพเลอร์ Python-to-C ++ สำหรับชุดย่อยของ Python ที่มีบางส่วน numpyการสนับสนุนมันทำหน้าที่เหมือน Numba และ Cython เล็กน้อย - คุณใส่คำอธิบายข้อโต้แย้งของฟังก์ชันและจากนั้นก็จะอธิบายเพิ่มเติมเกี่ยวกับคำอธิบายประกอบประเภทและรหัสเฉพาะทาง มันใช้ประโยชน์จากความเป็นไปได้ของการทำให้เป็นเวกเตอร์และความเป็นไปได้ของการทำให้เป็นคู่ขนานบน OpenMP มันรันโดยใช้ Python 2.7 เท่านั้น

คุณลักษณะที่น่าสนใจอย่างหนึ่งของ Pythran ก็คือมันจะพยายามหาโอกาสในการขนานโดยอัตโนมัติ (เช่นหากคุณใช้ a map) และเปลี่ยนเป็นรหัสคู่ขนานโดยไม่ต้องใช้ความพยายามเพิ่มเติมจากคุณ คุณยังสามารถระบุส่วนขนานโดยใช้pragma omp > directives ในแง่นี้มันให้ความรู้สึกคล้ายกับการสนับสนุน OpenMP ของ Cython

ด้านหลัง Pythran จะใช้ทั้งรหัสปกติและรหัสงูหลามและพยายามรวบรวมมันเป็น C ++ ที่เร็วมาก - เร็วกว่าผลของ Cython

คุณควรทราบว่าโครงการนี้ยังเด็กและคุณอาจพบข้อบกพร่อง คุณควรทราบด้วยว่าทีมพัฒนานั้นมีความเป็นมิตรและมีแนวโน้มที่จะแก้ไขข้อบกพร่องในเวลาไม่กี่ชั่วโมง


6

ฉันรู้ว่านี่เป็นหัวข้อเก่า แต่ฉันต้องการให้สิ่งที่ฉันคิดว่าเป็นข้อมูลที่เป็นประโยชน์

ส่วนตัวผมใช้ PyPy ซึ่งติดตั้งได้ง่ายโดยใช้ pip ฉันใช้ล่าม Python / PyPy แทนกันคุณไม่จำเป็นต้องเปลี่ยนรหัสเลยและฉันพบว่ามันเร็วกว่าการแปล Python ประมาณ 40 เท่า (Python 2x หรือ 3x) ฉันใช้ pyCharm Community Edition เพื่อจัดการรหัสของฉันและฉันรักมัน

ฉันชอบเขียนโค้ดในไพ ธ อนเพราะฉันคิดว่ามันช่วยให้คุณจดจ่อกับงานมากกว่าภาษาซึ่งเป็นข้อดีอย่างมากสำหรับฉัน และหากคุณต้องการให้เร็วยิ่งขึ้นคุณสามารถรวบรวมไบนารีสำหรับ Windows, Linux หรือ Mac ได้ (ไม่ตรงไปตรงมา แต่เป็นไปได้ด้วยเครื่องมืออื่น ๆ ) จากประสบการณ์ของฉันฉันได้รับความเร็ว 3.5x มากกว่า PyPy เมื่อรวบรวมหมายถึง 140x เร็วกว่าหลาม PyPy พร้อมใช้งานสำหรับ Python 3x และ 2x code และอีกครั้งหากคุณใช้ IDE เช่น PyCharm คุณสามารถแลกเปลี่ยนระหว่างพูด PyPy, Cython และ Python ได้อย่างง่ายดาย (ใช้เวลาเล็กน้อยในการเรียนรู้และตั้งค่าเบื้องต้น)

บางคนอาจเถียงกับฉันในเรื่องนี้ แต่ฉันคิดว่า PyPy นั้นเร็วกว่า Cython แต่พวกเขาทั้งสองทางเลือกที่ดี

แก้ไข:ฉันต้องการบันทึกย่อฉบับย่อเกี่ยวกับการรวบรวม: เมื่อคุณคอมไพล์ไบนารีของผลลัพธ์นั้นใหญ่กว่าสคริปต์ไพ ธ อนของคุณมากเพราะมันสร้างการพึ่งพาทั้งหมดลงไปเป็นต้น แต่จากนั้นคุณจะได้รับผลประโยชน์แตกต่างกันเล็กน้อย: ความเร็ว! ตอนนี้แอปจะทำงานบนเครื่องใด ๆ (ขึ้นอยู่กับระบบปฏิบัติการที่คุณรวบรวมถ้าไม่ได้ทั้งหมด lol) โดยไม่มี Python หรือไลบรารี่ก็จะทำให้รหัสของคุณงงงวยและพร้อมใช้งานในทางเทคนิค 'พร้อม' คอมไพเลอร์บางตัวยังสร้างรหัส C ซึ่งฉันไม่ได้ดูหรือดูว่ามันมีประโยชน์หรือไม่ก็พูดพล่อยๆ โชคดี.

หวังว่าจะช่วย


2
ฉันรู้ว่านี่เป็นความคิดเห็นที่เก่ากว่า แต่ขอบคุณ!
kfrncs

ไม่มีปัญหาฉันดีใจที่มีประโยชน์
jacktrader

คุณใช้ซอฟต์แวร์อะไรในการรวบรวมจากการตีความของ PyPy
Vasyl Vaskivskyi

ไม่ใช่เฉพาะ PyPy เพียงสคริปต์. py Nuitka ถ้าคุณต้องการ "ซอร์สโค้ดของ C / C ++ หรือซอร์สโค้ด C / C ++" และ PyInstaller ถ้าคุณต้องการไฟล์ที่เรียกใช้ (ง่ายกว่า) นอกจากนี้ยังมี py2exe แต่ฉันประสบความสำเร็จน้อยลง แต่ฉันก็มั่นใจว่าทุกอย่างดีขึ้น PyInstaller ยังเป็นแพลตฟอร์มข้ามไม่เพียง แต่สำหรับปฏิบัติการของ Windows (ทำงานได้กับ Linux และ Mac) Nuitka นั้นไม่เหมือนใครเพราะฉันคิดว่ามันเป็น "คอมไพเลอร์" เพียงตัวเดียวที่ให้ซอร์สโค้ดที่ใช้งานได้กลับมาซึ่งคุณสามารถเพิ่มประสิทธิภาพได้ในทางทฤษฎี มีอีกไม่กี่อย่างเช่น bbFreeze, cx_Freeze และ py2app แต่ฉันไม่ได้ลองเลย ขอให้โชคดี!
jacktrader

1
ฉันได้พบ PyPy เพื่อให้ทำงานได้เร็วกว่า Cython ด้วย ในการทดสอบครั้งหนึ่งฉันพบว่า PyPy มีความเร็วเท่ากับโปรแกรมรุ่น C ++ (การเรียงลำดับการแทรก)
Nv7

5

ฉันรู้ว่าคำตอบของวิธีแก้ปัญหาที่ค่อนข้างใหม่หายไป หากมีการใช้ Numpy ในรหัสฉันจะแนะนำให้ลอง Pythran:

http://pythran.readthedocs.io/

สำหรับฟังก์ชั่นที่ฉันลอง Pythran ให้ผลลัพธ์ที่ยอดเยี่ยมมาก ฟังก์ชั่นที่ได้นั้นเร็วพอ ๆ กับการเขียนโค้ด Fortran (หรือช้ากว่าเล็กน้อยเท่านั้น) และเร็วกว่าโซลูชัน Cython (ที่ได้รับการปรับให้เหมาะสม)

ข้อดีเมื่อเทียบกับ Cython คือคุณต้องใช้ Pythran ในฟังก์ชั่น Python ที่ปรับให้เหมาะกับ Numpy ซึ่งหมายความว่าคุณไม่จำเป็นต้องขยายลูปและเพิ่มประเภทสำหรับตัวแปรทั้งหมดในลูป Pythran numpy.ndarrayต้องใช้เวลาในการวิเคราะห์รหัสดังนั้นจึงมีความเข้าใจในการดำเนินงานใน

นอกจากนี้ยังเป็นข้อได้เปรียบอย่างมากเมื่อเทียบกับ Numba หรือโครงการอื่น ๆ จากการรวบรวมแบบทันเวลาซึ่ง (ความรู้ของฉัน) คุณต้องขยายลูปให้มีประสิทธิภาพจริงๆ แล้วโค้ดที่มีการวนซ้ำจะไม่มีประสิทธิภาพมากโดยใช้เพียง CPython และ Numpy ...

ข้อเสียเปรียบของ Pythran: ไม่มีคลาส! แต่เนื่องจากมีเพียงฟังก์ชั่นที่จำเป็นต้องปรับให้เหมาะสมเท่านั้นจึงต้องรวบรวมจึงไม่น่ารำคาญมาก

อีกจุดหนึ่ง: Pythran รองรับ OpenMP parallelism อย่างดี (และง่ายมาก) แต่ฉันไม่คิดว่ารองรับ mpi4py ...


4

http://code.google.com/p/py2c/ดูเหมือนความเป็นไปได้ - พวกเขายังกล่าวถึงในไซต์ของตน: Cython, Shedskin และ RPython และยืนยันว่าพวกเขากำลังแปลงรหัส Python เป็น C / C ++ บริสุทธิ์ซึ่งเร็วกว่า C มาก / C ++ เต็มไปด้วยการเรียก Python API หมายเหตุ: ฉันไม่ได้ลอง แต่ฉันจะไป ..


1
ดูเหมือนว่า Py2C ยังคงเป็นโครงการที่ยังไม่เสร็จ ไม่ได้รับการอัปเดตในอีกไม่กี่ปีดังนั้นอาจหมดอายุ
Anderson Green
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.