มีข้อ จำกัด ทางเทคนิคหรือคุณสมบัติภาษาที่ป้องกันไม่ให้สคริปต์ Python ของฉันเร็วเท่ากับโปรแกรม C ++ ที่เทียบเท่าหรือไม่


10

ฉันเป็นผู้ใช้ Python มาเป็นเวลานาน ไม่กี่ปีที่ผ่านมาฉันเริ่มเรียนรู้ C ++ เพื่อดูว่ามันสามารถให้อะไรในแง่ของความเร็ว ในช่วงเวลานี้ฉันจะใช้ Python เป็นเครื่องมือในการสร้างต้นแบบต่อไป ดูเหมือนว่านี่เป็นระบบที่ดี: การพัฒนาที่คล่องตัวด้วย Python การดำเนินการที่รวดเร็วใน C ++

เมื่อเร็ว ๆ นี้ฉันใช้ Python มากขึ้นอีกครั้งและเรียนรู้วิธีหลีกเลี่ยงข้อผิดพลาดและรูปแบบการต่อต้านทั้งหมดที่ฉันใช้อย่างรวดเร็วในปีก่อน ๆ กับภาษา ฉันเข้าใจว่าการใช้คุณสมบัติบางอย่าง (รายการความเข้าใจการแจกแจง ฯลฯ ) สามารถเพิ่มประสิทธิภาพได้

แต่มีข้อ จำกัด ทางเทคนิคหรือคุณสมบัติภาษาที่ป้องกันไม่ให้สคริปต์ Python ของฉันเร็วเท่ากับโปรแกรม C ++ ที่เทียบเท่ากันหรือไม่


2
ใช่มันสามารถ ดูPyPyสำหรับสถานะของศิลปะในคอมไพเลอร์ Python
Greg Hewgill

5
ตัวแปรทั้งหมดในไพ ธ อนนั้นเป็นโพลีมอร์ฟิคหมายความว่าชนิดของตัวแปรเป็นที่รู้จักกันเฉพาะที่รันไทม์ หากคุณเห็น (สมมติว่าเป็นจำนวนเต็ม) x + y ในภาษาที่เหมือน C พวกเขาจะเพิ่มจำนวนเต็ม ในไพ ธ อนจะมีสวิทช์ชนิดตัวแปรที่ x และ y จากนั้นเลือกฟังก์ชั่นการเติมที่เหมาะสมแล้วจะมีการตรวจสอบมากเกินและจะมีการเพิ่ม เว้นแต่ว่าหลามจะเรียนรู้การพิมพ์แบบคงที่ค่าใช้จ่ายนี้จะไม่หายไป
nwp

1
@nwp ไม่เป็นคนง่ายๆดู PyPy ปัญหาที่เปิดกว้างยังคงมีอยู่ ได้แก่ : วิธีเอาชนะความล่าช้าในการเริ่มต้นของคอมไพเลอร์ JIT วิธีหลีกเลี่ยงการจัดสรรกราฟวัตถุที่ซับซ้อนที่มีอายุการใช้งานยาวนานและวิธีใช้แคชโดยทั่วไป

คำตอบ:


11

ฉันชนกำแพงนี้ด้วยตัวเองเมื่อฉันทำงานเขียนโปรแกรม Python แบบเต็มเวลาเมื่อสองสามปีก่อน ฉันรัก Python ฉันทำจริงๆ แต่เมื่อฉันเริ่มทำการปรับแต่งประสิทธิภาพฉันมีแรงกระแทกบางอย่าง

Pythonistas ที่เข้มงวดสามารถแก้ไขฉันได้ แต่นี่คือสิ่งที่ฉันพบทาสีในจังหวะที่กว้างมาก

  • การใช้หน่วยความจำของ Python น่ากลัวมาก Python แสดงทุกอย่างเป็น dict ซึ่งมีประสิทธิภาพอย่างมาก แต่ก็มีผลลัพธ์ที่แม้แต่ชนิดข้อมูลที่เรียบง่ายก็มีขนาดใหญ่ ฉันจำได้ว่าตัวละคร "a" ใช้หน่วยความจำ 28 ไบต์ หากคุณกำลังใช้โครงสร้างข้อมูลขนาดใหญ่ใน Python ตรวจสอบให้แน่ใจว่าใช้ข้อมูลที่มีขนาดใหญ่หรือ scipy เนื่องจากมีการสำรองข้อมูลโดยการนำไบต์ไปใช้โดยตรง

ที่มีผลกระทบต่อประสิทธิภาพเนื่องจากหมายถึงมีระดับทางอ้อมเพิ่มขึ้นในขณะใช้งานนอกเหนือจากการหวดหน่วยความจำจำนวนมากเมื่อเทียบกับภาษาอื่น

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

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

ในตอนนี้ในการวัดประสิทธิภาพเว็บเซอร์วิส Python เปรียบเทียบได้ดีกับภาษาคอมไพล์แอคทีฟอื่น ๆ เช่น Ruby หรือ PHP แต่มันค่อนข้างล้าหลังเกือบทุกภาษาที่คอมไพล์แล้ว แม้แต่ภาษาที่รวบรวมภาษาระดับกลางและทำงานใน VM (เช่น Java หรือ C #) ก็ทำได้ดีกว่ามาก

นี่เป็นชุดทดสอบเกณฑ์มาตรฐานที่น่าสนใจอย่างยิ่งที่ฉันอ้างถึงเป็นครั้งคราว:

http://www.techempower.com/benchmarks/

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


2
สตริง "a" ไม่ใช่ตัวอย่างที่ดีสำหรับสัญลักษณ์แสดงหัวข้อแรก สตริง Java ยังมีค่าใช้จ่ายจำนวนมากสำหรับสตริงอักขระเดียวและ แต่ค่าใช้จ่ายคงที่ที่ตัดจำหน่ายค่อนข้างดีเป็นสตริงที่เติบโตในความยาว (1-4 ไบต์อักขระ oer ขึ้นอยู่กับรุ่นตัวเลือกการสร้างและเนื้อหาสตริง) คุณสิทธิเกี่ยวกับวัตถุที่ผู้ใช้กำหนด __slots__แต่อย่างน้อยผู้ที่ไม่ได้ใช้งาน PyPy น่าจะทำได้ดีกว่านี้มากในเรื่องนี้ แต่ฉันไม่รู้ที่จะตัดสิน

1
ปัญหาที่สองที่คุณชี้ให้เห็นนั้นเกี่ยวข้องกับการใช้งานเฉพาะอย่างและไม่เกี่ยวข้องกับภาษา ปัญหาแรกต้องการคำอธิบาย: สิ่งที่ "หนัก" 28 ไบต์ไม่ใช่ตัวอักขระ แต่ความจริงที่ว่ามันถูกบรรจุในคลาสสตริงที่มาพร้อมกับวิธีการและคุณสมบัติของตัวเอง การแทนอักขระเดียวเป็นอาร์เรย์ไบต์ (ตัวอักษร b'a ') "เท่านั้น" มีน้ำหนัก 18 ไบต์บน Python 3.3 และฉันแน่ใจว่ามีวิธีเพิ่มเติมในการเพิ่มประสิทธิภาพการจัดเก็บอักขระในหน่วยความจำหากแอปพลิเคชันของคุณต้องการจริงๆ
Red

C # สามารถรวบรวมได้ (เช่นเทคโนโลยี MS ที่กำลังจะถึง, Xamarin สำหรับ iOS)
Den

13

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

  • สคริปต์ระยะสั้นที่ใช้เช่นงานดูแลระบบ ระบบปฏิบัติการหลายระบบเช่น Ubuntu สร้างส่วนที่ดีของโครงสร้างพื้นฐานด้านบนของ Python: CPython นั้นเร็วพอสำหรับงาน แต่แทบจะไม่มีเวลาเริ่มต้นเลย ตราบใดที่มันเร็วกว่าทุบตีก็ดี

  • CPython ต้องมีซีแมนติกส์ที่ชัดเจนเนื่องจากเป็นการใช้งานอ้างอิง สิ่งนี้ช่วยให้การปรับให้เรียบง่ายเช่น "ปรับการใช้งานของตัวดำเนินการ foo" หรือ "รวบรวมรายการความเข้าใจให้เร็วขึ้น bytecode" แต่โดยทั่วไปจะแยกการเพิ่มประสิทธิภาพที่ทำลายข้อมูลเช่นฟังก์ชั่นอินไลน์

แน่นอนว่ามีการใช้งาน Python มากกว่าเพียงแค่ CPython:

  • Jython สร้างขึ้นจาก JVM JVM สามารถตีความหรือรวบรวม JITT ตามรหัสที่ให้มาและมีการปรับให้เหมาะสมที่แนะนำโดยโปรไฟล์ มันทนทุกข์ทรมานจากเวลาเริ่มต้นที่สูงและใช้เวลาสักครู่จนกว่า JIT จะเข้ามา

  • PyPy เป็นสุดยอดของ JITting Python VM PyPy เขียนใน RPython ซึ่งเป็นเซตย่อยที่ จำกัด ของ Python เซ็ตย่อยนี้ลบการแสดงออกบางอย่างออกจาก Python แต่อนุญาตให้อนุมานชนิดของตัวแปรใด ๆ ที่จะอนุมานแบบคงที่ VM ที่เขียนใน RPython นั้นสามารถ transpiled เป็น C ซึ่งให้ประสิทธิภาพเหมือน RPython C อย่างไรก็ตาม RPython ยังคงแสดงออกได้ดีกว่า C ซึ่งช่วยให้การพัฒนาเพิ่มประสิทธิภาพใหม่ได้เร็วขึ้น PyPy เป็นตัวอย่างของการคอมไพล์ bootstrapping PyPy (ไม่ใช่ RPython!) ส่วนใหญ่เข้ากันได้กับการใช้งานอ้างอิง CPython

  • Cython คือ (เช่น RPython) ภาษา Python ที่เข้ากันไม่ได้กับการพิมพ์แบบคงที่ มันยัง transpiles เป็นรหัส C และสามารถสร้างส่วนขยาย C สำหรับล่าม CPython ได้อย่างง่ายดาย

หากคุณยินดีที่จะแปลรหัส Python ของคุณเป็น Cython หรือ RPython คุณจะได้รับประสิทธิภาพเหมือน C อย่างไรก็ตามพวกเขาไม่ควรเข้าใจว่าเป็น“ ส่วนย่อยของ Python” แต่เป็น“ C กับไวยากรณ์ Pythonic” หากคุณเปลี่ยนไปใช้ PyPy รหัส Vanilla Python ของคุณจะได้รับความเร็วที่เพิ่มขึ้นอย่างมาก แต่จะไม่สามารถเชื่อมต่อกับส่วนขยายที่เขียนด้วย C หรือ C ++

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

  • ผู้สนับสนุนและเงินทุน แตกต่างจาก Java หรือ C # ไม่มี บริษัท ขับรถหลังภาษาเดียวที่มีความสนใจที่จะทำให้ภาษานี้ดีที่สุดในระดับเดียวกัน สิ่งนี้ จำกัด การพัฒนาเฉพาะสำหรับอาสาสมัครและเงินช่วยเหลือเป็นครั้งคราว

  • การรวมล่าช้าและการขาดการพิมพ์คงที่ใด ๆ Python ช่วยให้เราเขียนอึแบบนี้:

    import random
    
    # foo is a function that returns an empty list
    def foo(): return []
    
    # foo is a function, right?
    # this ought to be equivalent to "bar = foo"
    def bar(): return foo()
    
    # ooh, we can reassign variables to a different type – randomly
    if random.randint(0, 1):
       foo = 42
    
    print bar()
    # why does this blow up (in 50% of cases)?
    # "foo" was a function while "bar" was defined!
    # ah, the joys of late binding

    ใน Python ตัวแปรใด ๆ สามารถกำหนดใหม่ได้ตลอดเวลา สิ่งนี้จะช่วยป้องกันการแคชหรืออินไลน์ การเข้าถึงใด ๆ จะต้องผ่านตัวแปร การอ้อมนี้ทำให้ประสิทธิภาพลดลง แน่นอน: หากรหัสของคุณไม่ได้ทำสิ่งที่บ้าเช่นนั้นเพื่อให้ตัวแปรแต่ละตัวสามารถกำหนดชนิดที่แน่นอนก่อนการรวบรวมและตัวแปรแต่ละตัวจะได้รับมอบหมายเพียงครั้งเดียวจากนั้นในทางทฤษฎี - รูปแบบการดำเนินการที่มีประสิทธิภาพมากขึ้นสามารถเลือกได้ ภาษาที่มีสิ่งนี้อยู่ในใจจะให้วิธีการทำเครื่องหมายตัวระบุเป็นค่าคงที่และอย่างน้อยอนุญาตให้มีคำอธิบายประกอบประเภทที่เป็นตัวเลือก (“ การพิมพ์ทีละส่วน”)

  • โมเดลวัตถุที่น่าสงสัย เว้นแต่จะใช้ช่องมันเป็นเรื่องยากที่จะคิดออกว่าเขตข้อมูลที่วัตถุมี (วัตถุหลามเป็นหลักตารางแฮชของเขตข้อมูล) และแม้กระทั่งเมื่อเราอยู่ที่นั่นเราก็ยังไม่รู้เลยว่าฟิลด์เหล่านี้มีประเภทใด สิ่งนี้ช่วยป้องกันการแสดงวัตถุเป็นโครงสร้างที่รัดกุมแน่นหนาเช่นในกรณีของ C ++ (แน่นอนว่าการแสดงวัตถุ C ++ นั้นไม่เหมาะเช่นกัน: เนื่องจากลักษณะที่คล้ายกับ struct แม้กระทั่งช่องส่วนตัวที่เป็นของส่วนต่อประสานสาธารณะของวัตถุ)

  • เก็บขยะ ในหลายกรณี GC สามารถหลีกเลี่ยงได้อย่างสมบูรณ์ C ++ Type instance(args);ช่วยให้เราสามารถคงจัดสรรวัตถุซึ่งจะถูกทำลายโดยอัตโนมัติเมื่อขอบเขตปัจจุบันที่เหลือ: จนกว่าจะถึงเวลานั้นวัตถุยังมีชีวิตอยู่และสามารถยืมไปยังฟังก์ชั่นอื่น ๆ ได้ สิ่งนี้มักจะทำผ่าน "การอ้างอิงผ่าน" ภาษาอย่าง Rust อนุญาตให้คอมไพเลอร์ตรวจสอบแบบคงที่ว่าไม่มีตัวชี้ไปยังวัตถุดังกล่าวเกินอายุการใช้งานของวัตถุ รูปแบบการจัดการหน่วยความจำนี้สามารถคาดเดาได้ทั้งหมดมีประสิทธิภาพสูงและเหมาะสมกับกรณีส่วนใหญ่โดยไม่มีกราฟวัตถุที่ซับซ้อน น่าเสียดายที่ Python ไม่ได้ออกแบบมาโดยคำนึงถึงการจัดการหน่วยความจำ ในทางทฤษฎีแล้วการวิเคราะห์การหลบหนีสามารถนำมาใช้เพื่อค้นหากรณีที่ GC สามารถหลีกเลี่ยงได้ ในทางปฏิบัติโซ่วิธีง่าย ๆ เช่นfoo().bar().baz() จะต้องจัดสรรวัตถุระยะสั้นจำนวนมากบนฮีป (generational GC เป็นวิธีหนึ่งที่จะทำให้ปัญหานี้มีขนาดเล็ก)

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

    • fixed_size = [None] * sizeรายการที่มีขนาดที่เฉพาะเจาะจงที่สามารถสร้างขึ้นเช่น อย่างไรก็ตามหน่วยความจำสำหรับวัตถุภายในรายการนั้นจะต้องได้รับการจัดสรรแยกต่างหาก คมชัด c ++ std::array<Type, size> fixed_sizeที่เราสามารถทำได้

    • อาร์เรย์ที่บรรจุของประเภทเนทิฟเฉพาะสามารถสร้างได้ใน Python ผ่านarrayโมดูล builtin นอกจากนี้ยังnumpyนำเสนอบัฟเฟอร์ข้อมูลที่มีประสิทธิภาพพร้อมรูปร่างเฉพาะสำหรับชนิดตัวเลขดั้งเดิม

สรุป

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


8

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

ฉันจะไม่อ้างว่านี่เป็นการแลกเปลี่ยนที่ยอมรับไม่ได้ แต่เป็นพื้นฐานของธรรมชาติของ Python ที่การใช้งานจริงจะไม่เร็วเท่ากับการใช้งาน C ++


8

มีปัจจัยหลักสามประการที่ส่งผลกระทบต่อประสิทธิภาพของภาษาแบบไดนามิกทั้งหมดมากกว่าบางส่วน

  1. ค่าใช้จ่ายการตีความ ที่รันไทม์มีรหัสไบต์บางชนิดมากกว่าคำสั่งเครื่องและมีค่าใช้จ่ายคงที่ในการเรียกใช้รหัสนี้
  2. ส่งค่าโสหุ้ย ไม่ทราบเป้าหมายสำหรับการเรียกใช้ฟังก์ชันจนกว่าจะถึงเวลาใช้งานจริงและการค้นหาว่าวิธีการโทรใดจะมีค่าใช้จ่าย
  3. โอเวอร์เฮดการจัดการหน่วยความจำ ภาษาแบบไดนามิกจัดเก็บสิ่งต่าง ๆ ในวัตถุที่ต้องได้รับการจัดสรรและยกเลิกการจัดสรรและดำเนินการค่าใช้จ่าย

สำหรับ C / C ++ ค่าใช้จ่ายที่เกี่ยวข้องของ 3 ปัจจัยเหล่านี้เกือบเป็นศูนย์ คำสั่งจะถูกดำเนินการโดยตรงโดยหน่วยประมวลผลการจัดส่งจะใช้เวลามากที่สุดในทางอ้อมหรือสองหน่วยความจำฮีปจะไม่ถูกจัดสรรเว้นแต่คุณจะพูดอย่างนั้น รหัสที่เขียนได้ดีอาจเข้าใกล้ภาษาแอสเซมบลี

สำหรับ C # / Java ที่มีการรวบรวม JIT สองรายการแรกนั้นต่ำ แต่หน่วยความจำที่เก็บขยะมีค่าใช้จ่าย รหัสที่เขียนได้ดีอาจเข้าใกล้ 2x C / C ++

สำหรับ Python / Ruby / Perl ค่าใช้จ่ายของทั้งสามปัจจัยเหล่านี้ค่อนข้างสูง คิด 5x เมื่อเทียบกับ C / C ++ หรือแย่กว่านั้น (*)

โปรดจำไว้ว่ารหัสไลบรารีรันไทม์อาจเขียนเป็นภาษาเดียวกับโปรแกรมของคุณและมีข้อ จำกัด ด้านประสิทธิภาพเช่นเดียวกัน


(*) เมื่อการคอมไพล์ Just-In_Time (JIT) ถูกขยายไปยังภาษาเหล่านี้พวกเขาก็จะเข้าใกล้ (โดยทั่วไป 2x) ความเร็วของโค้ด C / C ++ ที่เขียนได้ดี

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


"จำได้ว่ารหัสไลบรารีรันไทม์อาจเขียนเป็นภาษาเดียวกับโปรแกรมของคุณและมีข้อ จำกัด ด้านประสิทธิภาพที่เหมือนกัน" และ "สำหรับ Python / Ruby / Perl ค่าใช้จ่ายของปัจจัยทั้งสามนี้ค่อนข้างสูงคิด 5 เท่าเทียบกับ C / C ++ หรือแย่กว่านั้น" จริงๆแล้วมันไม่จริง ตัวอย่างเช่นHashคลาสRubinius (หนึ่งในแกนข้อมูลหลักใน Ruby) ถูกเขียนใน Ruby และทำงานได้อย่างรวดเร็วกว่าบางครั้งเร็วกว่าHashคลาสของ YARV ซึ่งเขียนด้วย C และหนึ่งในเหตุผลก็คือส่วนใหญ่ของรันไทม์ของ Rubinius ระบบเขียนใน Ruby เพื่อให้สามารถ ...
Jörg W Mittag

ตัวอย่างเช่น ... อินไลน์โดยคอมไพเลอร์ Rubinius ตัวอย่างสุดขีดคือ Klein VM (VM สำหรับ metacircular สำหรับตนเอง) และ Maxine VM (VM สำหรับ metacircular สำหรับ Java) ซึ่งทุกอย่างแม้แต่รหัสวิธีการแจกจ่ายตัวเก็บรวบรวมขยะตัวจัดสรรหน่วยความจำชนิดดั้งเดิมโครงสร้างข้อมูลหลักและอัลกอริธึม ตนเองหรือจาวา ด้วยวิธีนี้แม้กระทั่งบางส่วนของคอร์ VM สามารถ inline เป็นรหัสผู้ใช้และ VM ก็สามารถคอมไพล์และปรับออปชั่นอีกครั้งโดยใช้ผลป้อนกลับแบบรันไทม์จาก userprogram
Jörg W Mittag

@ JörgWMittag: ยังคงเป็นจริง Rubinius มี JIT และรหัส JIT มักจะเต้น C / C ++ ตามเกณฑ์มาตรฐานของแต่ละบุคคล ฉันไม่สามารถหาหลักฐานใด ๆ ที่ว่าสิ่งที่เกี่ยวกับ metacircular นี้ทำเพื่อความเร็วได้มากในกรณีที่ไม่มี JIT [ดูการแก้ไขเพื่อความชัดเจนเกี่ยวกับ JIT.]
david.pfx

1

แต่มีข้อ จำกัด ทางเทคนิคหรือคุณสมบัติภาษาที่ป้องกันไม่ให้สคริปต์ Python ของฉันเร็วเท่ากับโปรแกรม C ++ ที่เทียบเท่ากันหรือไม่

ไม่มันเป็นเพียงแค่คำถามเกี่ยวกับเงินและทรัพยากรที่หลั่งไหลเข้ามาเพื่อทำให้ C ++ ทำงานได้เร็วขึ้นเมื่อเทียบกับเงินและทรัพยากรที่หลั่งไหลเข้ามาทำให้ Python ทำงานเร็วขึ้น

ตัวอย่างเช่นเมื่อ Self VM ออกมาไม่เพียง แต่เป็นภาษา OO แบบไดนามิกที่เร็วที่สุดเท่านั้น แต่เป็นช่วงเวลาภาษา OO ที่เร็วที่สุด แม้จะเป็นภาษาแบบไดนามิกอย่างไม่น่าเชื่อ (ยกตัวอย่างเช่น Python, Ruby, PHP หรือ JavaScript) แต่ก็เร็วกว่าการใช้ C ++ ส่วนใหญ่ที่มีอยู่

แต่ซันยกเลิกโครงการ Self (ภาษา OO สำหรับผู้ใหญ่ทั่วไปเพื่อพัฒนาระบบขนาดใหญ่) เพื่อมุ่งเน้นไปที่ภาษาสคริปต์ขนาดเล็กสำหรับเมนูภาพเคลื่อนไหวในกล่องรับสัญญาณโทรทัศน์ (คุณอาจเคยได้ยินเกี่ยวกับมันเรียกว่า Java) ไม่มี เงินทุนเพิ่มเติม ในเวลาเดียวกัน Intel, IBM, Microsoft, Sun, Metrowerks, HP และคณะ ใช้เงินจำนวนมหาศาลและทรัพยากรทำให้ C ++ รวดเร็ว ผู้ผลิตซีพียูได้เพิ่มฟีเจอร์ให้กับชิปเพื่อทำให้ C ++ รวดเร็ว ระบบปฏิบัติการถูกเขียนหรือแก้ไขเพื่อให้ C ++ รวดเร็ว ดังนั้น C ++ จึงรวดเร็ว

ฉันไม่คุ้นเคยกับ Python มากฉันเป็นคน Ruby ดังนั้นฉันจะยกตัวอย่างจาก Ruby: Hashคลาส (เทียบเท่าในหน้าที่และความสำคัญdictใน Python) ในการใช้ Rubinius Ruby เขียนด้วย Ruby บริสุทธิ์ 100%; แต่มันก็แข่งขันได้ดีและบางครั้งก็มีประสิทธิภาพสูงกว่าHashคลาสใน YARV ซึ่งเขียนด้วยมือที่ปรับ C และเมื่อเทียบกับระบบ Lisp หรือ Smalltalk เชิงพาณิชย์บางส่วน .

ไม่มีสิ่งใดใน Python ที่ทำให้ช้าลง มีคุณสมบัติในโปรเซสเซอร์และระบบปฏิบัติการในปัจจุบันที่สร้างความเสียหายให้กับ Python (เช่นหน่วยความจำเสมือนเป็นที่ทราบกันดีว่ามีประสิทธิภาพในการรวบรวมขยะ) มีคุณสมบัติที่ช่วยให้ C ++ แต่ไม่ช่วย Python (ซีพียูสมัยใหม่พยายามหลีกเลี่ยงการพลาดแคชเนื่องจากมีราคาแพงมากโชคไม่ดีที่การหลีกเลี่ยงการใช้แคชนั้นยากเมื่อคุณมี OO และ polymorphism แต่คุณควรลดต้นทุนของการแคช คิดถึง. Azul Vega CPU ซึ่งออกแบบมาสำหรับ Java ทำสิ่งนี้)

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

เราได้เห็น ECMAScript แล้วจะเกิดอะไรขึ้นถ้าผู้เล่นเพียงคนเดียวที่จริงจังกับการแสดง ภายในหนึ่งปีเรามีประสิทธิภาพเพิ่มขึ้น 10 เท่าทั่วกระดานสำหรับผู้ค้ารายใหญ่ทั้งหมด

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