ภาษา C# เร็วกว่า ภาษา JAVA

ภาษา C# เร็วกว่า ภาษา JAVA
จากการทดสอบโดยใช้โปรแกรมวัดความเร็ว (benchmark) พบว่า application ที่พัฒนาด้วยภาษา C# มีประสิทธิภาพสูงกว่า application เดียวกันที่ถูกพัฒนาโดยใช้ภาษา Javaการวัดความเร็วของตัวภาษาเองล้วน ๆ เป็นสิ่งไม่มีความหมาย เพราะเหมือนกับพูดว่าภาษาไทยหรือภาษาอังกฤษอันไหนเร็วกว่ากัน
แต่การวัดความเร็วของapplication ที่ถูกพัฒนาด้วยภาษาใดภาษาหนึ่งเปรียบเทียบกันสามารถทำได้
ผลลัพธ์ที่ได้จะส่อให้เห็นประสิทธิภาพของตัวแปลภาษาและ runtime ของภาษานั้น ๆ
ซอฟต์แวร์ที่ใช้ตรวจวัดความเร็วในหัวข้อนี้เป็น Open Source ที่พัฒนาร่ามกันโดยโปรแกรมเมอร์จำนวนมาก สามารถใช้เทียบวัดภาษาต่าง ๆ ได้หลายภาษา
อาทิ Ada, C, Chapel, C#, C++, Dart, Erlang, F#, Fortran, Go, Hack, Haskell, Java, JavaScript, Lisp, Lua, OCaml, Pascal, Perl, PHP, Python ฯลฯ
ฮาร์ดแวร์ที่ใช้ในการทดสอบเป็น quad-core 2.4Ghz Intel® Q6600® มีแรม 4GB และมีฮาร์ดดิสก์ 250GB SATA II
run ในระบบปฏิบัติการ Ubuntu™ 18.04 Linux x64 4.15.0-20-generic และ Windows
กระบวนการวัดความเร็วเป็นดังนี้
- แต่ละโปรแกรมจะรันและวัดความเร็วโดยใช้ข้อมูล input น้อยที่สุด จากนั้นนำ output ไปเก็บในไฟล์แล้วนำไปเทียบกับค่าที่ควรจะเป็น ถ้าพบว่าค่าของเอาต์พุตใกล้เคียงกับค่าที่ควรจะเป็น โปรแกรมจะรันและวัดค่าถัดไปจนกว่าจะหมด
- ถ้าโปรแกรมให้ output เป็นค่าที่ควรจะเป็นภายในช่วงเวลาที่กำหนด คือไม่เกิน 120 วินาที จะทำการทดสอบซ้ำอีก 5 ครั้ง
- ในกรณีที่โปรแกรมให้ output ไม่ตรงกับค่าที่ควรจะเป็นภายในเวลาหนึ่งชั่วโมง โปรแกรมจะถูกทำให้หยุดการทำงาน แต่ถ้าโปรแกรมให้ output เป็นค่าที่ควรจะเป็นภายในช่วงเวลาที่กำหนดคือไม่เกิน 120 วินาที โปรแกรมวัดค่าเริ่มจะทำการทดสอบซ้ำอีก 5 ครั้ง
- ผลลัพธ์จากการวัดค่าที่นำมาแสดงนี้ จะมีทั้งแบบให้ output เป็นค่าที่ควรและให้ output ไม่ตรงกับค่าที่ควรจะเป็น โดยจะนำค่าที่ดีที่สุดมาแสดง (จากการวัดหกครั้ง)
- โปรแกรมที่ทำงานนานกว่าห้าชั่วโมงจะจะถูกทำให้หยุดการทำงาน
โดยกระบวนการย่อยนี้จะเชื่อมต่อกับ input output และ error ผ่านทาง pipe เป็นของมันเอง
ในกรณีที่ทดสอบในระบบปฏิบัติการ Linux หน่วย secs คือวินาที่ โดยจะนับจากเมื่อกระบวนการย่อยเริ่มทำงานไปจนถึงเมื่อกระบวนการย่อยสิ้นสุด
การวัดทำโดยใช้ฟังก์ชัน time.time() หน่วย CPU ได้มาจากค่า usr+sys rusage ที่กระบวนการย่อยใช้
โดยใช้ฟังก์ชัน os.wait3 ซึ่งจะรอให้กระบวนการย่อยทำงานเสร็จและจะคืนค่าเป็น tuple ที่ประกอบด้วยเลขประจำตัวของงานและสถานะการทำงาน
ในกรณีที่ทดสอบในระบบปฏิบัติการวินโดวส์ หน่วย secs คือวินาที
โดยเริ่มนับเมื่อกระบวนการย่อยเริ่มทำงานไปจนถึงเมื่อกระบวนการย่อยสิ้นสุด
การวัดทำโดยใช้ฟังก์ชัน QueryPerformanceCounter ซึ่งเป็นฟังก์ชันใน Kernel32.dll
ส่วนหน่วย CPU ได้มาจากการเรียกใช้ฟังก์ชัน QueryInformationJobObject (hJob, JobObjectBasicAccountingInformation) แล้วดูค่า TotalKernelTime + TotalUserTime
ในทั้งสองกรณีตัวเลขรวมช่วงเวลาที่โปรแกรมใช้ตอนสตาร์ทอัพด้วย
วิธีตรวจวัดการใช้งานหน่วยความจำ
ในกรณีที่เป็น Linux ทำได้โดยการดูค่า GLIBTOP_PROC_MEM_RESIDENT ของโปรแกรมและของกระบวนการย่อยทุก ๆ 0.2 วินาที
แน่นอนว่าการวัดนี้จะไม่ได้ผล หากโปรแกรมทำงานนานไม่ถึง 0.2 วินาที
ในกรณีที่เป็นระบบปฏิบัติการ windows การวัดทำได้
โดยเรียกใช้ฟังก์ชัน QueryInformationJobObject (hJob, JobObjectBasicAccountingInformation) แล้วดูค่า PeakJobMemoryUsed

จากตารางแสดงผลลัพธ์การวัดความเร็วจะเห็นว่าภาษา C# ทำแต้มได้ดีกว่าภาษา JAVA ในการวัดทั้งสามแบบ วิธีอ่านค่าในตารางนี้คือค่าน้อยดีกว่าค่ามาก เช่น
การวัดแบบ fannkuch-redux
(คือ CLR ของ .NET Core ที่มีอยู่ในระบบปฏิบัติการวินโดวส์ แมคโอเอส และลินุกซ์)
มีประสิทธิภาพดีกว่าสภาพแวดล้อมในการรันโปรแกรมของภาษาจาวา (คือ JVM ที่มีอยู่ในแทบจะทุกระบบปฏิบัติการ)
การวัดแบบ fannkuch-redux
- ภาษา C# ใช้เวลาทำงาน 14.44 วินาที
- ขณะที่ภาษา JAVA ใช้เวลา 18.27 วินาที
- ภาษา C# ใช้เวลาทำงาน 2.09 วินาที
- ขณะที่ภาษาJAVA ใช้เวลา 2.27 วินาที
- ภาษา C# ใช้เวลาทำงาน 4.07 วินาที
- ขณะที่ภาษาJAVA ใช้เวลา 4.38 วินาที
(คือ CLR ของ .NET Core ที่มีอยู่ในระบบปฏิบัติการวินโดวส์ แมคโอเอส และลินุกซ์)
มีประสิทธิภาพดีกว่าสภาพแวดล้อมในการรันโปรแกรมของภาษาจาวา (คือ JVM ที่มีอยู่ในแทบจะทุกระบบปฏิบัติการ)

ที่เห็นในภาพคือสคริปต์ภาษา python ทำหน้าที่แสดงตัวอย่างการเขียนโค้ดเพื่อวัดเวลาการทำงานของโปรแกรมแบบง่ายที่สุด
นำมาแสดงเพื่อให้เห็นแนวคิดของการวัดค่าความเร็วของโปรแกรม ส่วนโปรแกรมวัดความเร็วที่ใช้จริงจะซับซ้อนกว่านี้มาก
โค้ดบรรทัดที่ 1 อิมพอร์ทเพคเก็จชื่อ time เพราะเราต้องการใช้ฟังก์ชัน time() เพื่อทำหน้าที่จับเวลา
โค้ดบรรทัดที่ 4-11 แสดงวิธีจับเวลาการทำงานแบบลูป
เป็นอย่างไรกันบ้างครับ จากบทความนี้ ที่แสดงให้เห็นว่า ภาษา C# นั้นเร็วกว่า ภาษา JAVA ที่เขียนให้ได้ application เดียวกัน
ที่สุดแล้ว ผู้พัฒนาโปรแกรมอาจเลือกภาษาในการพัฒนาด้วยปัจจัยต่างๆ มากกว่าเรื่องความเร็วแค่เพียงอย่างเดียว
นำมาแสดงเพื่อให้เห็นแนวคิดของการวัดค่าความเร็วของโปรแกรม ส่วนโปรแกรมวัดความเร็วที่ใช้จริงจะซับซ้อนกว่านี้มาก
โค้ดบรรทัดที่ 1 อิมพอร์ทเพคเก็จชื่อ time เพราะเราต้องการใช้ฟังก์ชัน time() เพื่อทำหน้าที่จับเวลา
โค้ดบรรทัดที่ 4-11 แสดงวิธีจับเวลาการทำงานแบบลูป
- โปรแกรมส่วนที่ถูกวัดความเร็วการทำงานคือโค้ดบรรทัดที่ 5-9 ซึ่งทำหน้าที่คูณเลขหนึ่งหมื่นครั้ง
- โค้ดบรรทัดที่ 4 นำค่าจากฟังก์ชัน time() มาเก็บไว้ในตัวแปร start นี่คือเวลาที่โปรแกรมเริ่มทำงาน
- โค้ดบรรทัดที่ 5 เรียกฟังก์ชัน range() เพื่อสร้างลิสต์ที่มีจำนวนหน่วยหนึ่งหมื่นหน่วยแล้วนำไปเก็นในตัวแปร a
- โค้ดบรรทัดที่ 6 ประกาศตัวแปร b ให้เป็นลิสต์ว่าง ๆ ไว้เพื่อจะใช้เก็บผลลัพธ์จากการคูณ
- โค้ดบรรทัดที่ 7-8 นำหน่วยใน a มาคุณกับสองแล้วนำไปเก็บใน b วนการทำงานเช่นนี้ตั้งแต่หน่วยแรกไปจนถึงหน่วยที่หมื่น
- โค้ดบรรทัดที่ 9 นำค่าจากฟังก์ชัน time() มาเก็บไว้ในตัวแปร end นี่คือเวลาที่โปรแกรมสิ้นสุดการทำงาน
- โค้ดบรรทัดที่ 10 นำค่า end ลบ start ออกแสดงที่ console ค่านี้คือผลลัพธ์การทำงานซึ่งคือเวลาที่โค้ดบรรทัดที่ 5-9 ใช้ในการทำงานโดยมีเป็นหน่วยวินาที
เป็นอย่างไรกันบ้างครับ จากบทความนี้ ที่แสดงให้เห็นว่า ภาษา C# นั้นเร็วกว่า ภาษา JAVA ที่เขียนให้ได้ application เดียวกัน
ที่สุดแล้ว ผู้พัฒนาโปรแกรมอาจเลือกภาษาในการพัฒนาด้วยปัจจัยต่างๆ มากกว่าเรื่องความเร็วแค่เพียงอย่างเดียว