ฉันเป็น C ++ และนักพัฒนา C # ฉันได้พัฒนาแอปพลิเคชั่น C # ตั้งแต่เบต้าแรกของเฟรมเวิร์ก. NET และฉันมีประสบการณ์มากกว่า 20 ปีในการพัฒนาแอปพลิเคชัน C ++ ประการแรกรหัส C # จะไม่เร็วกว่าแอปพลิเคชัน C ++ แต่ฉันจะไม่พูดถึงการสนทนาที่ยาวนานเกี่ยวกับโค้ดที่มีการจัดการวิธีการทำงานเลเยอร์ระหว่างการทำงานการจัดการหน่วยความจำภายในระบบประเภทไดนามิกและตัวรวบรวมขยะ อย่างไรก็ตามให้ฉันดำเนินการต่อโดยบอกว่าเกณฑ์มาตรฐานที่ระบุไว้ที่นี่ทั้งหมดให้ผลลัพธ์ที่ไม่ถูกต้อง
ให้ฉันอธิบาย: สิ่งแรกที่เราต้องพิจารณาคือคอมไพเลอร์ JIT สำหรับ C # (.NET Framework 4) ตอนนี้ JIT สร้างโค้ดเนทีฟสำหรับ CPU โดยใช้อัลกอริธึมการเพิ่มประสิทธิภาพต่างๆ (ซึ่งมีแนวโน้มที่จะก้าวร้าวมากกว่าเครื่องมือเพิ่มประสิทธิภาพ C ++ เริ่มต้นที่มาพร้อมกับ Visual Studio) และชุดคำสั่งที่ใช้โดยคอมไพลเลอร์. NET JIT เป็นการสะท้อนที่ใกล้เคียงกับ CPU จริงมากขึ้น บนเครื่องดังนั้นการแทนที่บางอย่างในรหัสเครื่องสามารถทำได้เพื่อลดรอบนาฬิกาและปรับปรุงอัตราการตีในแคชไปป์ไลน์ของ CPU และสร้างการเพิ่มประสิทธิภาพไฮเปอร์เธรดเพิ่มเติมเช่นคำสั่งของเราในการจัดลำดับใหม่และการปรับปรุงที่เกี่ยวข้องกับการทำนายสาขา
สิ่งนี้หมายความว่าเว้นแต่คุณจะคอมไพล์แอปพลิเคชัน C ++ ของคุณโดยใช้พารามิเตอรที่ถูกต้องสำหรับรุ่น RELEASE (ไม่ใช่รุ่น DEBUG) แอปพลิเคชัน C ++ ของคุณอาจทำงานช้ากว่าแอปพลิเคชัน C # หรือ. NET ที่เกี่ยวข้อง เมื่อระบุคุณสมบัติโปรเจ็กต์บนแอปพลิเคชัน C ++ ของคุณตรวจสอบให้แน่ใจว่าคุณเปิดใช้งาน "การเพิ่มประสิทธิภาพเต็มรูปแบบ" และ "โปรดปรานโค้ดด่วน" หากคุณมีเครื่อง 64 บิตคุณต้องระบุเพื่อสร้าง x64 เป็นแพลตฟอร์มเป้าหมายมิฉะนั้นโค้ดของคุณจะถูกเรียกใช้ผ่านเลเยอร์ย่อยการแปลง (WOW64) ซึ่งจะลดประสิทธิภาพลงอย่างมาก
เมื่อคุณดำเนินการปรับแต่งที่ถูกต้องในคอมไพเลอร์ฉันจะได้รับ. 72 วินาทีสำหรับแอปพลิเคชัน C ++ และ 1.16 วินาทีสำหรับแอปพลิเคชัน C # (ทั้งในรุ่นรุ่น) เนื่องจากแอปพลิเคชัน C # เป็นแอปพลิเคชันพื้นฐานมากและจัดสรรหน่วยความจำที่ใช้ในการวนซ้ำบนสแต็กและไม่ได้อยู่บนฮีปจึงทำงานได้ดีกว่าแอปพลิเคชันจริงที่เกี่ยวข้องกับวัตถุการคำนวณที่หนักหน่วงและชุดข้อมูลขนาดใหญ่ ดังนั้นตัวเลขที่ให้จึงเป็นตัวเลขในแง่ดีที่เอนเอียงไปทาง C # และกรอบงาน. NET แม้จะมีอคตินี้ แต่แอปพลิเคชัน C ++ ก็ทำงานเสร็จในเวลาเพียงครึ่งเวลากว่าแอปพลิเคชัน C # ที่เทียบเท่า โปรดทราบว่าคอมไพเลอร์ Microsoft C ++ ที่ฉันใช้ไม่มีการเพิ่มประสิทธิภาพไปป์ไลน์และไฮเปอร์เธรดที่ถูกต้อง (โดยใช้ WinDBG เพื่อดูคำแนะนำในการประกอบ)
ตอนนี้ถ้าเราใช้คอมไพเลอร์ Intel (ซึ่งเป็นความลับของอุตสาหกรรมในการสร้างแอปพลิเคชันประสิทธิภาพสูงบนโปรเซสเซอร์ AMD / Intel) รหัสเดียวกันจะทำงานใน. 54 วินาทีสำหรับปฏิบัติการ C ++ เทียบกับ. 72 วินาทีโดยใช้ Microsoft Visual Studio 2010 ท้ายที่สุดผลลัพธ์สุดท้ายคือ. 54 วินาทีสำหรับ C ++ และ 1.16 วินาทีสำหรับ C # ดังนั้นโค้ดที่สร้างโดยคอมไพลเลอร์. NET JIT จึงใช้เวลานานกว่าไฟล์ปฏิบัติการ C ++ ถึง 214% เวลาส่วนใหญ่ที่ใช้ใน. 54 วินาทีคือการรับเวลาจากระบบและไม่ได้อยู่ในลูปนั่นเอง!
สิ่งที่ขาดหายไปในสถิติคือเวลาเริ่มต้นและเวลาล้างข้อมูลซึ่งไม่รวมอยู่ในการกำหนดเวลา แอปพลิเคชัน C # มักจะใช้เวลาในการเริ่มต้นและการยกเลิกมากกว่าแอปพลิเคชัน C ++ เหตุผลเบื้องหลังสิ่งนี้ซับซ้อนและเกี่ยวข้องกับรูทีนการตรวจสอบความถูกต้องของรหัสรันไทม์. NET และระบบย่อยการจัดการหน่วยความจำซึ่งทำงานเป็นจำนวนมากในตอนเริ่มต้น (และท้ายที่สุด) ของโปรแกรมเพื่อเพิ่มประสิทธิภาพการจัดสรรหน่วยความจำและขยะ นักสะสม.
เมื่อวัดประสิทธิภาพของ C ++ และ. NET IL สิ่งสำคัญคือต้องดูรหัสแอสเซมบลีเพื่อให้แน่ใจว่ามีการคำนวณทั้งหมดอยู่ที่นั่น สิ่งที่ฉันพบคือการไม่ใส่โค้ดเพิ่มเติมใน C # โค้ดส่วนใหญ่ในตัวอย่างด้านบนจะถูกลบออกจากไบนารี นี่เป็นกรณีของ C ++ เช่นกันเมื่อคุณใช้เครื่องมือเพิ่มประสิทธิภาพเชิงรุกเช่นตัวที่มาพร้อมกับคอมไพเลอร์ Intel C ++ ผลลัพธ์ที่ฉันให้ไว้ข้างต้นถูกต้อง 100% และผ่านการตรวจสอบในระดับการประกอบ
ปัญหาหลักของฟอรัมจำนวนมากบนอินเทอร์เน็ตที่มีมือใหม่จำนวนมากฟังโฆษณาชวนเชื่อทางการตลาดของ Microsoft โดยไม่เข้าใจเทคโนโลยีและอ้างว่า C # เร็วกว่า C ++ ข้ออ้างคือตามทฤษฎีแล้ว C # เร็วกว่า C ++ เนื่องจากคอมไพเลอร์ JIT สามารถปรับโค้ดให้เหมาะสมกับ CPU ได้ ปัญหาของทฤษฎีนี้คือมีท่อประปาจำนวนมากที่มีอยู่ในกรอบงาน. NET ที่ทำให้ประสิทธิภาพการทำงานช้าลง ท่อประปาที่ไม่มีในแอปพลิเคชัน C ++ นอกจากนี้นักพัฒนาที่มีประสบการณ์จะรู้จักคอมไพเลอร์ที่เหมาะสมที่จะใช้สำหรับแพลตฟอร์มที่กำหนดและใช้แฟล็กที่เหมาะสมเมื่อรวบรวมแอปพลิเคชัน บนแพลตฟอร์ม Linux หรือโอเพ่นซอร์สนี่ไม่ใช่ปัญหาเนื่องจากคุณสามารถแจกจ่ายซอร์สของคุณและสร้างสคริปต์การติดตั้งที่คอมไพล์โค้ดโดยใช้การเพิ่มประสิทธิภาพที่เหมาะสม บน windows หรือแพลตฟอร์มซอร์สแบบปิดคุณจะต้องแจกจ่ายไฟล์ปฏิบัติการหลาย ๆ ไฟล์โดยแต่ละไฟล์มีการปรับให้เหมาะสม ไบนารีของ windows ที่จะปรับใช้จะขึ้นอยู่กับ CPU ที่ตรวจพบโดยโปรแกรมติดตั้ง msi (โดยใช้การดำเนินการแบบกำหนดเอง)