Hard Fight : Java vs. Python vs. Ruby

tags:

imageผมเป็นคนที่ชอบศึกษาเรื่องภาษาเขียนโปรแกรม ดังจะเห็นได้จาก จำนวนบล็อกที่ผมเขียนเกี่ยวกับภาษาเขียนโปรแกรม ที่มีมากกว่าในเรื่องอื่น ๆ จากการศึกษาโดยการเข้าไปหาข้อมูลในอินเตอร์เนตพบว่า เรื่องภาษาเขียนโปรแกรมเป็นเรื่องศาสนา คือ เป็นเรื่องที่มีพื้นฐานอยู่บนความเชื่อ มากกว่าเหตุผล

ทฤษฎีทางความเชื่อเกี่ยวกับภาษาเขียนโปรแกรมจำนวนมาก ได้ถูกกล่าวอ้างโดยไม่ได้รับข้อพิสูจน์ โดยเฉพาะจากเหล่าสาวกของภาษานั้น ๆ บางครั้งเวลาผมอ่านก็เคลิ้มตามไปเหมือนกัน บางครั้งก็อดตั้งคำถามไม่ได้ว่า มันจะจริงเหรอ ???

หมายเหตุ : ขอโฆษณาต้นฉบับหน่อยครับ ที่ BioLawCom.De :D

ผมจึงรู้สึกว่า น่าจะเขียนบล็อกขึ้นมาหนึ่งบล็อก เพื่อเปรียบเทียบคุณสมบัติต่าง ๆ ของภาษาเขียนโปรแกรมขึ้นมาหนึ่งบล็อก เพื่อเปรียบเทียบให้เห็นกันจะ ๆ และพยายามเป็นกลางให้มากที่สุด (อันนี้แหละยาก) เผื่อว่าใครจะเอาข้อมูลไปใช้ประกอบการตัดสินใจ โดยภาษาที่ผมจะนำมาเปรียบมวยมีด้วยกัน 3 ภาษา คือ Java, Python และ Ruby เพราะเป็นภาษาที่ได้รับความนิยมในขณะนี้ และดูที่อนาคตจะไปได้สวย (จริง ๆ อยากเขียน C# เหมือนกัน แต่ดูเหมือน C# จะแผ่วไปเยอะในช่วงหลัง)

อันที่จริงมีคนเปรียบมวย Python กับ Java ไว้แล้วเยอะเหมือนกัน ไม่ว่าจะเป็น Python & Java: Side by Side Comparison
(รู้สึกหน้านี้จะเสีย ลองไปอ่านที่ Google-Cache ดูครับ), C++ vs Java vs Python vs Ruby : a first impression และ Python vs. Perl vs. Java vs. C++ Runtimes แต่ส่วนมากมักเป็นข้อมูลเก่า (ยกเว้น C++ vs Java vs Python vs Ruby : a first impression ข้อมูลค่อนข้างใหม่) ผมจึงอยากอัพเดดข้อมูลบางอย่างเพิ่มเติมลงไป และทดสอบโดยใช้โปรแกรมที่ใกล้เคียงกับการใช้งานจริงมากที่สุด

About me

ก่อนอื่นผมต้องแนะนำตัว เกี่ยวกับพื้นหลังการเขียนโปรแกรมของผมก่อนครับ เพื่อให้คนอ่านใช้ประกอบวิจรณญาณในการอ่าน

ทุกวันนี้ผมทำงานโดยใช้ Python ในการเขียนโปรแกรม Simulation เกี่ยวกับเคเบิลใยแก้วนำแสง ดังนั้น คนอ่านไม่ต้องแปลกใจครับ หากผมจะลำเอียงไปทาง Python แต่ผมจะพยายามรักษาความเป็นกลางไว้ให้มากที่สุดครับ

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

ผมไม่เคยศึกษา Ruby อย่างเป็นเรื่องเป็นราว แต่ก็ผ่าน ๆ ตามาบ้าง โดยการใช้งาน Ruby on Rails ความรู้ Ruby ผมจึงเป็นแบบ งูงู ปลาปลา อย่าถือสากันนะครับ :D

About this fight

การเปรียบมวยครั้งนี้ ผมได้เขียนขึ้นโดยวิเคราะห์จากการเขียนโปรแกรม โปรแกรมค้นหาข้อมูลสำหรับ CMS ซึ่งเดิมทีนั้น ผมเขียนขึ้นโดยใช้ PHP แล้วนำมาเขียนใหม่โดยใช้ Java, Python และ Ruby โดยมีการตัดโค้ดบางส่วนออก และปรับปรุงอีกเล็กน้อย เพื่อให้เหมาะสมกับการทดสอบ

ส่วนการทดสอบความเร็วนั้น ผมได้อ้างอิงตาม Python vs. Perl vs. Java vs. C++ Runtimes โดยมาปรับปรุงสำหรับ Ruby และเพิ่มการทดสอบในกรณีอื่น ๆ เข้าไปอีกเล็กน้อย

ในแต่ละยกผมจะให้คะแนน แต่ละภาษาโดยให้เป็น image ยิ่งมากยิ่งดี โดยมีคะแนนเต็ม imageimageimageimageimage (คิดถึงตอนเรียนอนุบาลเลย)

Round 1 : The first impression

ในยกนี้ผมวิเคราะห์ตามความรู้สึกของผม ที่ได้เขียนโปรแกรมในภาษานั้น ๆ เป็นครั้งแรก ประกอบกับความรู้สึกของเพื่อน ๆ ที่เขียนโปรแกรมภาษานั้น ๆ เป็น

  • Java : image : เป็นภาษาที่เหมาะกับวิศวกรซอพท์แวร์ แต่ไม่ค่อยถูกโฉลกกับคนวงการอื่น ๆ ในครั้งแรกที่เริ่มเขียน Java อะไร ๆ ก็ดูยากไปหมด ผมและเพื่อนทุกคนเห็นพ้องต้องกันตอนเรียน Java ว่า Java ยากกว่า C อีก อีกทั้งตัวภาษาไม่เอื้อต่องานประเภท Quick and Dirty คือลองเขียนเล่น ๆ สั้น ๆ คนที่จะเขียนโปรแกรม Java โปรแกรมแรกได้นั้น ต้องรู้จัก JRE, JDK, class, object, public, static, void, main ก่อนถึงจะเขียนได้ อีกทั้งยังเจอ Concept แปลก ๆ ที่คนที่ไม่เคยเขียน Java มาก่อน ก็ต้องงงไปตาม ๆ กัน เช่น Interface, Abstact Class, Iteration, Type Cast เป็นต้น สรุปคือ กว่าจะเขียน Java เป็นต้องใช้เวลาค่อนข้างนาน
  • Python : imageimageimageimage : คงเหมือนกับภาษา Script ภาษาอื่น ๆ ที่ไม่ต้องรู้อะไรมากก็ลงมือเขียนได้เลย มี Interactive-Console ให้ใช้งาน ลองเล่นไปตามเรื่องตามราว แต่สิ่งที่กวนประสาทมาก ๆ คือ Indent เป็นเรื่องที่ต้องใช้เวลาในการปรับตัวกันนานพอสมควร
  • Ruby : imageimageimageimageimage : ครั้งแรกที่ลองใช้งาน อะไร ๆ ก็ดูง่ายไปหมด หากรู้จักภาษา Script อื่น ๆ มาก่อน Ruby แล้ว การเรียนรู้ Ruby ก็จะใช้เวลาน้อยมาก

Round 2 : Community

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

  • Java : imageimageimageimageimage : เนื่องจาก Java เป็นภาษาที่ได้รับความนิยมสูงสุด มีบริษัทยักษ์ใหญ่จำนวนมากให้การสนับสนุน Java และเลือก Java เป็นภาษาหลักในพัฒนาซอพท์แวร์ของตัวเอง อีกทั้งในขณะนี้ Java กลายเป็น OpenSource เป็นที่เรียบร้อยแล้ว ดังนั้น Community ของ Java จึงแข็งแกร่งไร้เทียมทาน
  • Python : imageimageimageimageimage: Python เป็น OpenSource โดยกำเนิด และเป็นภาษาที่ได้รับความนิยมมากขึ้นเรื่อย ๆ มีองค์กรณ์สนับสนุนอย่างเป็นทางการมากมาย (PSF, Google, Zope) แม้ความนิยมในตัว Python ยังไม่เทียบเท่า Java แต่ความแข็งแกร่งของ Community ก็ไม่ได้เป็นรอง Java แม้แต่น้อย
  • Ruby :imageimageimageimage: แม้ว่า Ruby จะเป็นภาษาที่ค่อนข้องใหม่ แต่ในระยะเวลาสองปีที่ผ่านมา Ruby ได้รับความนิยมเพิ่มขึ้นอย่างรวดเร็ว สาเหตุก็เนื่องมาจาก Ruby on Rails ความแข็งแกร่งของ Community ของ Ruby จึงเพิ่มขึ้นอย่างน่าจับตามอง แม้กระนั้นก็ตาม Community ของ Ruby ยังอยู่ในภาวะสร้างตัว จึงยังไม่แข็งกร่งเท่าภาษาเขียนโปรแกรมรุ่นพี่อย่าง Java และ Python แต่คาดว่าอีกปีหรือสองปี Ruby อาจเทียบชั้นมาตีเสมอได้ไม่ยาก

Round 3 : Library

  • Java : imageimageimageimage : เนื่องจาก Java เป็นภาษาที่ได้รับความนิยมอย่างสูง จึงไม่ใช่เรื่องแปลกที่ Java จะมี Library ให้เลือกใช้มากมาย โดยเฉพาะอย่างยิ่งการเขียนโปรแกรมเชิงธุรกิจ แต่ Library ส่วนใหญ่ของ Java ได้รับการออกแบบมาซับซ้อนเกินไป ทำให้ใช้ยาก อีกทั้งยังขาด Library สำหรับโปรแกรมทางวิทยาศาสตร์อีกจำนวนมาก
  • Python : imageimageimageimage : แม้ว่า Library ของ Python คลอบคลุมการใช้งานมากกว่า Java (ทางวิทยาศาสตร์, Image Processing, Latex, 3D-Rendering, etc.) แต่ Library ส่วนใหญ่ยังมีมาตรฐานไม่เทียบเท่าของ Java ส่วนหนึ่งเนื่องมาจากเป็นโครงการ OpenSource ขนาดเล็ก
  • Ruby : imageimageimage : ความเป็นภาษาใหม่ของ Ruby ทำให้ Ruby มี Library ให้เลือกใช้ยังไม่มากนัก แต่ Library ของ Ruby ก็น่าจับตามอง เนื่องเพราะเป็น Library ที่ใช้งานง่าย และมีมาตรฐาน เมื่อเปรียบเทียบกับ Java และ Python

Round 4 : Time to code

  • Java : imageimage : ใครบอกว่า Java เขียนง่ายผมคนหนึ่งล่ะที่ไม่เชื่อ คนส่วนใหญ่บอกว่า Java เขียนง่ายกว่า C++ ผมเห็นด้วยเพียงครึ่งเดียว Concept ของ Java แม้จะทำให้เขียนโปรแกรมง่ายกว่า C++ ก็จริง แต่ก็เข้าใจยากกว่าเหมือนกัน (แค่ Itration อ. ที่สอนต้องใช้เวลาอธิบายอยู่หลายอาทิตย์ กว่าพวกผมจะเข้าใจ) และเนื่องจาก Java ยังเป็น Compiled Language อยู่ การลองโน่นลองนี่จึงไม่ใช่เรื่องง่าย เพราะต้องเสียเวลาในการ Compile อีกทั้งความพยายามออกแบบ Java ให้ Common มากที่สุด ก็ทำให้ Java ซับซ้อนเกินกว่าเหตุ
  • Python : imageimageimageimageimage : ความเป็น Script ของ Python ทำให้การเขียนโค้ดด้วย Python รวดเร็วทันใจอยู่แล้ว บวกกับคอนเซพท์ที่เข้าใจง่ายของ Python ยิ่งทำการเขียนโค้ดของ Python เร็วขึ้นไปอีก เครื่องมือในการหาข้อผิดพลาดที่พร้อม คุณภาพโค้ดที่ได้ก็สูง เพราะโดนบังคับโดยตัวภาษา โครงสร้างของภาษาที่รองรับโครงการขนาดใหญ่ โดยส่วนตัวผมเห็นว่า Python น่าจะเป็นภาษาที่เขียนโค้ดได้เร็วที่สุดในขณะนี้
  • Ruby : imageimageimageimage : คุณสมบัติดี ๆ หลายอย่างของ Perl และ Python ถูกสอดแทรกลงใน Ruby ได้อย่างลงตัว แม้ว่า Ruby จะเป็นภาษาที่ใช้เครื่องหมายมากเกินไป (ออกแนว Perl) ทำให้โค้ดที่ได้อ่านยากไปบ้าง แต่ก็ถูกทดแทนด้วยคอนเซพท์หลายอย่างที่ไม่เหมือนใคร (symbol, attr_reader) ในขั้นต้นการเขียนโค้ดด้วย Ruby อาจเร็วกว่า Python แต่ในระยะยาว Ruby อาจประสบปัญหาเดียวกับ Perl คือ Write only coding

Round 5 : How does the language do ?

5.1 : Block

  • Java : imageimageimageimageimage : สำหรับผมแล้วการแบ่งบล็อกด้วยวงเล็บปีกกา {} เป็นการแบ่งบล็อกที่ผมชอบมากที่สุด เพราะสามารถทำได้ง่าย รวดเร็ว และชัดเจน แม้ว่าจะมีปัญหาเกิดขึ้นบ้าง เวลาที่มีบล็อกซ้อนบล็อกมากเกินไป แต่ปัญหานี้ไม่ว่าจะใช้วิธีการแบ่งบล็อกแบบไหน ก็เกิดขึ้นได้ทั้งนั้น การเลี่ยงการเขียนบล็อกซ้อนบล็อกจึงน่าจะเป็นทางออกที่ดีกว่า
  • Python : imageimageimageimage : แม้ว่าการแบ่งบล็อกด้วย indentation มีข้อดีหลายอย่าง ทั้งง่าย รวดเร็ว เป็นการบังคับให้คนเขียนโปรแกรมเขียนโค้ดที่อ่านง่าย แต่ก็มีอันตรายแอบแฝงหลายอย่าง เช่น การใช้ Tabalator ผสมกับการเว้นวรรค ขนาด indentation ที่ไม่เท่ากัน การเขียนโปรแกรมด้วย Python จึงต้องใช้ Editor ที่มีคุณภาพพอสมควร เพื่อป้องกันปัญหาดังกล่าว อีกทั้งต้องมีการตกลงกันระหว่าคนเขียนโปรแกรมว่าจะใช้ indentation แบบใด
  • Ruby : imageimageimage : การแบ่งบล็อกด้วย begin และ end แม้ว่าจะทำให้อ่านง่ายขึ้น แต่ก็ง่ายกว่าการใช้วงเล็บปีกกาไม่มากนัก Ruby เองก็ไม่ใช่ภาษาที่อ่านง่ายอยู่แล้ว การใช้ begin และ end จึงไม่มีข้อได้เปรียบที่ชัดเจน นอกจากจะทำให้โค้ดยาวขึ้น

5.2 : Loop

  • Java : imageimageimage : การวนลูปของ Java เริ่มต้นเดิมทีได้นำวิธีการของ C มาใช้ จากนั้นก็เพิ่ม Iteration เข้ามา แม้ว่า Iteration จะได้เปรียบ for ธรรมดาอยู่หลายอย่าง แต่ก็ทำให้โค้ดที่ได้อ่านยาก ต้องเขียนโค้ดยาว งง ๆ คนส่วนมากจึงยังคงใช้ for ธรรมดามากกว่า Iteration ใน Java 5 จึงได้มี for-each เพิ่มเข้ามา แต่ก็ยัง for-each ที่ยัง งง ๆ อยู่ ถึงตอนนี้ผมยังคอมไพล์โปรแกรมที่มี for-each ไม่ผ่านเลยครับ
  • Python : imageimageimageimageimage : คอนเซพท์ for-loop ของ Python ถือว่าเป็นคอนเซพท์ที่ดีมาก มีการนำ iteration มาใช้โดยที่คนเขียนไม่ต้องทำความเข้าใจเรื่อง iteration แต่อย่างใด for-each เป็นการวนลูปที่เร็วที่สุดใน Python (เร็วกว่า while) มีฟังก์ชั่น zip() ให้ใช้ ทำให้สามารถใช้ for-each กับข้อมูลสองชุดที่มีขนาดเท่ากันพร้อมกันได้
  • Ruby : imageimageimageimage : คอนเซพท์วนลูปของ Ruby คล้ายคลึงกับของ Python มาก ข้อเสียเดียวที่ผมมองเห็นในการวนลูปของ Ruby คือ incosistence Ruby มีการวนลูปหลายรูปแบบเกินไป ทำให้เกิดความสับสนในการใช้งานในบางครั้ง

5.3 : Container

  • Java : imageimage : ตอนผมเรียน Java อ.ที่สอนท่านชอบบอกว่า Collection-Classes ของ Java มันเจ๋งอย่างไรบ้าง หากเปรียบมวยกับ Array ของ C++ มันก็เจ๋งกว่าจริง ๆ นั่นแหละ แต่มันซับซ้อนมาก ๆ มากเกินไป การทำความเข้าใจ Collection-Classes ของ Java ให้แตกฉาน เป็นศาสตร์ และศิลป์ในตัว ต้องใช้เวลานาน มีจำนวน Classes ให้เลือกใช้มากเกินไป ทั้งที่แต่ละ Class ก็ไม่ต่างกันมาก การนำข้อมูลดิบใส่ลงไปใน Container ก็ไม่ใช่เรื่องง่าย ๆ (ดูตัวออย่างโปรแกรม)
  • Python : imageimageimageimageimage : ใน Python มี Container เพียงสามแบบ คือ [List], {Dictionary} และ (Tuple) สามารถนำไปใช้งานง่าย คลอบคลุมทุกการใช้งาน เจ๋งไหม
  • Ruby : imageimageimageimage : คอยเซพท์ Container ของ Ruby เหมือนของ Python ทุกอย่าง แต่ไม่มี Tuple ให้ใช้

Round 6 : OOP

  • Java : imageimageimageimageimage : Java เป็นภาษาเขียนโปรแกรมที่นำทฤษฎี OOP มาใช้งานได้เต็มรูปแบบ และสมบูรณ์ที่สุด มีเพียง C# เท่านั้น ที่สามารถเทียบชั้นกับ Java ได้ในเรื่องนี้ แต่คำถามคือ เรามีความจำเป็นเพียงใด ในการใช้ OOP เต็มรูปแบบ
  • Python : imageimage : แม้ว่า Python จะรองรับการเขียนโปรแกรมแบบ OOP แต่ผมก็มองว่าเป็น OOP แบบขำ ๆ มีคอนเซพท์ OOP หลายอย่างที่ขาดใน Python (public, private, protected, interface, abstact calss, etc.) อีกทั้งทุกอย่างใน Python ไม่จำเป็ต้องเป็น Object สำหรับคนที่เรียน วิชา Software Engineering หรือ Software Architect มา อาจเริ่มต้นกับ Python ไปไม่ถูกเหมือนกัน แต่สิ่งเหล่านี้ถูกทดแทนได้โดย Meta- , Functional-Programming และ Dynamic Typing
  • Ruby : imageimageimageimageimage : Ruby อาจไม่รองรับ OOP เท่า Java แต่ดีกว่า Python และทำหน้าที่ OOP ได้อย่างไม่ขาดตกบกพร่อง OOP ในส่วนที่ขาดไปของ Ruby สามารถทดแทนได้ด้วย Dynamic Typing

Round 7 : Web-Development

  • Java : imageimageimage : แม้ว่า Java จะสร้างชื่อเสียงของตัวเองด้วยการใช้งานบนอินเตอร์เนต แต่ Framework เกี่ยวกับ Web-Development ของ Java ก็ไม่เคยประสบความสำเร็จอย่างจริงจัง Applet โดนโลกลืมอย่างน่าสงสาร Servlet และ JSP ก็โดน PHP กินส่วนแบ่ง ทิ้งห่างอย่างไม่เห็นฝุ่น เพราะมันดันใช้ยาก และตะกละตะกลาม แม้ว่าจะมี Web-Framework ใหม่ ๆ ออกมาให้ใช้งานมากมาย แต่ก็กินส่วนแบ่งกันเอง และไม่มีนวัตกรรมใหม่ ๆ ที่น่าสนใจ
  • Python : imageimageimageimage : Plone ถือเป็น Killer Application ของ Python และเป็นเครื่องยืนยันได้ถึงคุณภาพด้านนี้ของ Python ได้อย่างดี อีกทั้ง Google และ YouTube ต่างก็หันมาใช้ Python อย่างออกหน้าออกตา สำหรับ Framework ก็มีทั้ง Zope , Django และ Turbo-Gear ให้เลือกใช้ แต่ปัญหามันอยู่ตรงนี้แหละครับ มันมีให้เลือกใช้เยอะเกินไปจน inconsistence
  • Ruby : imageimageimageimageimage : บอกได้คำเดียวครับว่า Rails มันสุดยอด

Round 8 : GUI

  • Java : imageimage : เป็นจุดอ่อนของที่ติดตัว Java มานานนับปี AWT , SWT และ Swing ต่างก็มีจุดอ่อนจุดแข็งของตัวเอง แต่เมื่อเปรียบเทียบทั้งสามกับ GUI ภาษาอื่น บอกได้เลยครับว่ามันห่วย สาเหตุก็เนื่องมาจาก Java มันเป็น Manage Code จึงไม่สามารถดึงพลังของ CPU มาใช้สำหรับ GUI ได้เท่า Native Code
  • Python : imageimageimageimageimage : Python เป็นภาษาเขียนโปรแกรมที่มี GUI ให้เลือกใช้มากที่สุดภาษาหนึ่ง ไม่ว่าจะเป็น Tk, Qt, KDE, GTK, Gnome, wxPython และทุก GUI-Toolkit ต่างก็เป็น GUI-Toolkit ที่มีประสิทธิภาพทั้งสิ้น
  • Ruby : imageimageimageimage : ความเป็นภาษาใหม่ของ Ruby ทำให้ Ruby ยังมี GUI ให้ใช้ไม่มากนัก แต่ไม่นานครับ ตอนนี้นักพัฒนาโปรแกรมของ Ruby ต่างเร่งผลิต Toolkit เหล่านี้ให้เราใช้งานอยู่ อีกสองสามปี ผมคิดว่า GUI ของ Ruby คงเทียบชั้น Python ได้ไม่ยาก

Round 9 : ETC.

9.1 : Tools

  • Java : imageimageimageimageimage : เนื่องจาก Java เป็นภาษาที่เขียนยาก แต่มีคนใช้เยอะ เลยมี IDE ดี ๆ ให้เลือกใช้งานหลากหลายตามไปด้วย สองผู้นำในวงการ IDE ของ Java ได้แก่ NetBeans และ Eclipse ซึ่งทั้งสองเป็น IDE ที่มีคุณภาพสูง แถมทั้งคู่เป็น OpenSource อีกต่างหาก นอกจาก IDE แล้ว Java ยังมีเครื่องมืออื่น ๆ ให้เลือกใช้อย่างจุใจ
  • Python : imageimageimage : IDLE เป็นเครื่องมือมาตรฐานที่ติดตัวมากับ Python อันประกอบด้วย Editor และ Interactive-Python ซึ่งเป็นเครื่องมือที่เหมาะสำหรับงานขั้นพื้นฐานเท่านั้น แม้ว่า Python จะเป็นภาษาที่ค่อนข้างได้รับความนิยม แต่ถือว่ามีเครื่องมือจำพวก IDE ให้เลือกใช้งานน้อยมาก
  • Ruby : imageimage : ความเป็นน้องใหม่ของ Ruby ทำให้ Ruby เสียเปรียบในหลาย ๆ ด้าน ไม่เว้นแม้แต่ด้านเครื่องมือการพัฒนาโปรแกรม โดยส่วนตัวผมคิดว่า ในอนาคตเราก็อาจไม่มีเครื่องมืออลังการอย่าง NetBeans หรือ Eclipse สำหรับ Ruby หรือ Python มาใช้งานกัน เพราะคุณสมบัติของภาษา Script ทำให้เครื่องมือต่าง เป็นเพียงเครื่องอำนวยความสดวก มากกว่าเครื่องมือจำเป็น

9.2 : Platform

  • Java : imageimageimageimageimage : คอนเซพท์ Write once run any where ของ Java นั้น ถือเป็นนวรรตกรรมบรรลือโลก ที่ถึงตอนนี้ยังไม่มีใครมาเทียบรัศมี (.NET ฟังดูดี แต่ในความเป็นจริงมันงี่เง่า เพราะใช้งานได้เฉพาะ OS ความหวังจึงน่าจะอยู่ที่ Mono) Byte-Code ที่ได้ไม่ต้องเปลี่ยนแปลงใด ๆ ก็ใช้งานได้ทุก OS ดังนั้นเรื่อง Plattform ต้องยกให้ Java เขาไป
  • Python : imageimageimageimage : แม้ว่า Python จะรองรับหลาย OS ไม่แพ้ Java แต่โค้ดบางส่วน ก็ต้องมีการแก้ไขเพื่อให้เข้ากับ OS โดยเฉพาะในส่วนที่ใช้ Module os ของ Python อีกทั้งการนำไปใช้งาน ก็เป็นการนำซอร์สโค้ดไปใช้ ไม่ได้เป็น Byte-Code อย่าง Java
  • Ruby : imageimageimageimage : เหมือน Python ครับ :P

Round 10 : Performance

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

Platform

Computer-Modell : Notebook Samsung R55
CPU : Intel Core 2 Duo Centrino T5500
CPU-Freq : 1830 MHz
RAM : 1 GB
OS : Ubuntu 6.04 LTS

Java-1.4 : gij (GNU libgcj) version 4.1.0 (Ubuntu 4.1.0-1ubuntu8)
Java-1.6 : Java(TM) SE Runtime Environment (build 1.6.0-b105)
Python : Python 2.4.3 (#2, Oct 6 2006, 07:52:30) , [GCC 4.0.3 (Ubuntu 4.0.3-1ubuntu5)] on linux2
Ruby : ruby 1.8.4 (2005-12-24) [i486-linux]

หมายเหตุ สำหรับ Java ให้ยึด Java 1.6 เป็นหลักครับ เพราะ Java ของ GNU มันไม่ดีเท่า Java 1.6 ของ Sun แต่สูสี Java 1.4 ของค่ายอื่น ๆ อยู่ (แต่จากการคาดการณ์ ผมคิดว่าคนส่วนใหญ่ยังใช้ Java 1.4 อยู่นะ)

Speed

image

Test Java 1.4 Java 1.6 Python Ruby
Console 12.2 13.9 11.7 12.8
Hash 7.4 2.0 3.6 11.3
IO 1.2 0.7 1.9 6.5
List 2.2 0.4 0.4 5.5
Math 0.7 0.5 0.3 4.4
Real-World-Application 14.8 3.6 0.9 1.5

Memory-usage

image

Test Java 1.4 Java 1.6 Python Ruby
Console 17.9 8.9 17.5 1.6
Hash 17.7 8.9 2.4 40.7
IO 17.9 8.9 2.3 1.6
List 17.9 8.9 2.3 4.1
Math 24.7 22.3 13.9 19.1
Real-World-Application 45.3 37.2 6.2 16.7

Console

ในส่วนนี้ไม่มีใครได้เปรียบเสียเปรียบอย่างได้ชัดในเรื่องความเร็ว แต่การใช้ Memory ต้องยกใช้ Ruby ส่วน Python มีการใช้ Memory มากผิดปกติ สาเหตุน่าจะมาจาก range() ที่ต้องผลิต list ขนาดยักษ์

Java

  1. public class test {
  2. public static void main(String[] args) {
  3. for (int i = 0; i < 1000000; i++) {
  4. System.out.println(i);
  5. }
  6. }
  7. }
  8.  

Python

  1. for x in range(1000000):
  2. print x
  3.  

Ruby

  1. 1000000.times do |i|
  2. puts i
  3. end
  4.  

Hash

Ruby ทำได้ไม่ดีนัก ทั้งในเรื่องความเร็ว และการใช้ Memory ในทางกลับกัน Python กลับทำได้ดีจนน่าแปลกใจ มีการใช้ Memory ขั้นต่ำสุด ความเร็วห่างจาก Java 1.6 ไม่มากนัก

Java

  1. import java.util.*;
  2.  
  3. public class test {
  4. public static void main(String[] args) {
  5. for (int i = 0; i < 6000; i++) {
  6. Map x = new HashMap();
  7. for (int j = 0; j < 1000; j++) {
  8. Integer I=new Integer(i);
  9. Integer J=new Integer(j);
  10. x.put(J,I);
  11. x.get(J);
  12. }
  13. }
  14. }
  15. }
  16.  

Python

  1. for i in range(6000):
  2. x={}
  3. for j in range(1000):
  4. x[j]=i
  5. x[j]
  6.  

Ruby

  1. 6000.times do |i|
  2. x={}
  3. 1000.times do |j|
  4. x[j] = i
  5. x[j]
  6. end
  7. end
  8.  

IO

ในเรื่องความเร็ว ไม่มีอะไรน่าแปลกใจ แต่การใช้ Memory ของทุกภาษาอยู่ในขั้นต่ำสุด

Java

  1. import java.io.*;
  2.  
  3. public class test
  4. {
  5. public static void main(String[] args) {
  6. try {
  7. File f = new File("/tmp/scratch");
  8. new FileWriter(f)));
  9. for (int i = 0; i < 1000000; i++) {
  10. pw.print(i);
  11. }
  12. pw.close();
  13. }
  14. catch(IOException ioe) {
  15. ioe.printStackTrace();
  16. }
  17. }
  18. }
  19.  

Python

  1. f=open('/tmp/scratch','wb')
  2. for i in xrange(1000000):
  3. f.write(str(i))
  4. f.close()
  5.  

Ruby

  1. f = File.new("/tmp/scratch", "w")
  2. 1000000.times do |i|
  3. f.syswrite(i.to_s)
  4. end
  5. f.close
  6.  

List

งานนี้มีการใช้ทริกเล็กน้อยสำหรับ Python ทำให้ Python มีความเร็วเทียบเท่า Java-1.6 ขึ้นมาได้ ส่วน Ruby รั้งท้ายเหมือนเดิม

Java

  1. import java.util.*;
  2.  
  3. public class test {
  4. public static void main(String[] args) {
  5. List initial = new ArrayList();
  6. initial.add("a");
  7. initial.add("b");
  8. initial.add("c");
  9. initial.add("d");
  10. initial.add("e");
  11. initial.add("f");
  12. initial.add("g");
  13.  
  14. for (int i = 0; i < 3000; i++) {
  15. List v = new ArrayList(initial);
  16. for (int j = 0; j < 1000; j++) {
  17. v.add(new Integer(j));
  18. v.get(j);
  19. }
  20. }
  21. }
  22. }
  23.  

Python

  1. a = map(lambda x : ['a','b','c','d','e','f','g']+range(1000),range(3000))
  2. for i in a : i
  3.  

Ruby

  1. 3000.times do |i|
  2. v=['a','b','c','d','e','f','g']
  3. 1000.times do |j|
  4. v.push(j)
  5. v[j]
  6. end
  7. end
  8.  

Math

การทดสอบในส่วนนี้ค่อนข้างใกล้เคียงการใช้งานจริงที่ผมใช้อยู่ ที่ตลกคือ การจัดการ Memory และระบบ Typecast ของ Java ตอนแรกผมใช้ Class ArrayList ในการเก็บข้อมูล แต่ก็ต้องมานั่งปวดหัวกับเรื่อง Typecast มากกว่าจะมาจดจ่อกับตัวโปรแกรม เลยต้องหันใช้ double[] แทน แต่ตัว double[] ก็เก็บข้อมูลได้เพียง 2000000 หน่วย และไม่สามารถประกาศตัวแปรขนาด 2000000 หน่วย ติดต่อกันได้เกิน 3 ตัวแปร ไม่งั้นมีเรื่อง ส่วน Ruby ก็ช้าจนน่าเกลียด

Java

  1. import java.lang.Math;
  2.  
  3. public class test {
  4. public static void main(String[] args) {
  5. double[] x = new double[200000];
  6. double[] gauss = new double[200000];
  7. double[] laplace = new double[200000];
  8. double[] si = new double[200000];
  9. double[] sisqr = new double[200000];
  10. double[] bp = new double[200000];
  11. for(int i = 0 ; i < 200000; i++){
  12. x[i] = (i/10000.0)-10.0;
  13. gauss[i] = Math.exp(-1.0 * x[i] * x[i]);
  14. laplace[i] = Math.exp(-1.0 * Math.abs(x[i]));
  15. si[i] = Math.sin(x[i]*Math.PI)/(x[i]*Math.PI);
  16. sisqr[i] = si[i]*si[i];
  17. bp[i] = si[i]*Math.cos(x[i]*100);
  18. }
  19. }
  20. }
  21.  

Python

  1. import numpy
  2. x = numpy.arange(-10,10,0.0001)
  3. gauss = numpy.exp(-(x**2))
  4. laplace = numpy.exp(-numpy.abs(x))
  5. si = numpy.sin(x*numpy.pi)/(numpy.pi)
  6. sisqr = si**2
  7. bp = si*numpy.cos(x*100)
  8.  

Ruby

  1. x = []
  2. gauss = []
  3. laplace = []
  4. si = []
  5. sisqr = []
  6. bp = []
  7. 200000.times do |i|
  8. x.push( (i / 10000.0)-10.0 )
  9. gauss.push( Math.exp(-1.0 * x[i] * x[i]) )
  10. laplace.push(Math.exp(-1.0 * x[i].abs ))
  11. si.push(Math.sin(x[i]* Math::PI) / (x[i] * Math::PI))
  12. sisqr.push(si[i]*si[i])
  13. bp.push(si[i]*Math.cos(x[i]*100))
  14. end
  15.  

Real-World-Application

การทดสอบสุดท้าย ผมคิดว่าน่าจะใกล้เคียงกับการใช้งานจริงมากที่สุด ในการทดสอบนี้ตัวโปรแกรมต้องสร้าง Query เพื่อสอบถามไปยังฐานข้อมูลก่อน เมื่อได้ข้อมูลมาแล้ว จึงเปลี่ยนแปลงรูปแบบข้อมูลด้วย RegEx และ Splitจากนั้นข้อมูลจะถูกเก็บไว้ใน Hash สุดท้ายก็แสดงผลข้อมูลออกมาทาง Console จะเห็นได้ว่า การทดสอบนี้ มีส่วนประกอบที่ใช้ในการเขียนโปรแกรมเวบไซท์ค่อนข้างครบ

ข้อมูลที่อยู่ในฐานข้อมูลก็คือข้อมูลของ BioLawCom.De คำที่ผมใช้หาในฐานข้อมูลคือ ตัวอักษร a ข้อมูลที่ได้มีทั้งสิ้น 690 rows

สิ่งที่น่าเบื่อมากใน Java คือ Typecast และไม่สามารถบรรจุข้อมูลลงใน Hash และ List ได้แบบง่าย ๆ อย่าง Python กว่าผมจะเขียนโปรแกรมนี้ด้วย Java ได้ต้องใช้เวลานานมาก เพราะต้องแก้ไขข้อผิดพลาดเกือบทุกครั้งที่คอมไพล์ ส่วน Ruby และ Python นั้นมีความคล้ายคลึงกันมาก ต่างกันเพียงแค่รายละเอียดเล็กน้อยเท่านั้น

โปรแกรมที่ได้จาก Ruby และ Python มีขนาดใกล้เคียงกันมาก แต่ของ Java มีขนาดใหญ่กว่าเกือบสองเท่า เวลาที่ใช้ในการเขียนอาจจะมากกว่าห้าหรือสิบเท่า ผลที่ออกมาก็ไม่คุ้มกับเวลาที่เสียไปเอาเสียเลย Java ทั้งใช้เวลามากกว่า และใช้ Memory มากกว่า น่าผิดหวังมาก ส่วน Python นั้นนำโด่ง ทิ้งห่าง Ruby เกือบสองเท่า

(เนื่องจากโค้ดยาวมาก ดังนั้น ผมเลยแยกโค้ดออกมาต่างหาก สามารถดาวน์โหลดได้ที่ Real.zip ครับ)

  • Java : imageimageimage : มีความเร็วเหนือกว่า Ruby และ Python ในเรื่องง่าย ๆ และพื้น ๆ เท่านั้น โปรแกรมที่มีความซับซ้อนมากขึ้น Java จะเริ่มตะกละ และอุ้ยอ้าย การจะเขียน Application ขนาดใหญ่ด้วย Java จึงต้องเตรียมรับเรื่องนี้ไว้ให้ดี
  • Python : imageimageimageimageimage : ต้องยกให้เป็นผู้ชนะในครั้งนี้ครับ เพราะมีความเร็วสูงสุดใน 4 จาก 6 การทดสอบ ในการทดสอบที่ Python ช้ากว่า Java ก็มีความแตกต่างเกิดขึ้นไม่มากนัก
  • Ruby : imageimageimage : แม้ว่า Ruby จะไม่ชนะในการทดสอบใดเลย แต่ก็รักษาตำแหน่งการใช้ Memory น้อยได้โดยตลอด แม้ว่าการทดสอบพื้น ๆ Ruby จะเป็น looser แต่ในการใช้งานจริง โดยเฉพาะ Web-Application Ruby ก็สามารถรักษาความเร็วของตัวเองได้ดีทีเดียว แต่สำหรับโปรแกรมจำพวก Simulation ลืม Ruby ไปได้เลยครับ

Conclusion

ในส่วนของผลรวมคะแนน ผมคิดว่าแต่ละคนคงมีตัวคูณสำหรับคะแนนจากแต่ละยกที่ไม่เท่ากัน สำหรับผม ในเรื่อง Peformance x 3 และ Time to code x 2 และ Python ก็เป็นแชมป์ในครั้งนี้ แต่ทั้งหมดทั้งสิ้นก็เป็นการให้คะแนนโดยผมเพียงคนเดียว ซึ่งอาจไม่ตรงใจหลาย ๆ คน ก็สามารถให้คะแนนแต่ละส่วนกันได้ตามความพอใจครับ

ทั้งนี้และทั้งนั้น ในส่วนของ Performance และ Time to code เป็นส่วนสำคัญมาก และ ผลก็คงเปลี่ยนแปลงจากนี้ไปได้ไม่มาก จากสองส่วนนี้ผมพอจะสรุปได้ว่า Java เป็นอะไรที่ไม่น่าใช้เอาเสียเลย เพราะต้องเสียเวลาเขียนโค้ดนาน แต่โปรแกรมที่ได้กลับไม่มีข้อได้เปรียบใด ๆ

สำหรับบริษัทพัฒนาโปรแกรม หากเลือกใช้ Java เหมือนกับเป็นการเสียเงินลงทุนไป 5-10 เท่าโดยใช่เหตุ ส่วนหนึ่งต้องลงทุนไปกับการเขียนโค้ดที่ต้องใช้เวลานานขึ้น ส่วนหนึ่งต้องเสียไปกับการซื้อเครื่องมือมาช่วยในการพัฒนาโปรแกรม ส่วนหนึ่งต้องเสียไปในการอบรมพนักงาน และอื่น ๆ อีกมากมาย

ข้อได้เปรียบเดียวของ Java คือ เครื่องมือที่พร้อม และมีทฤษฎีรองรับมากมาย ทฤษฎีการวางโครงสร้างระบบส่วนมาก ใช้ Java เป็นภาษาอ้างอิง ในส่วนของทฤษฎีผมมองว่า เราสามารถนำมาปรับใช้กับ Python และ Ruby ได้ไม่ยาก

ส่วน Python นั้นเป็นภาษาที่สามารถนำไปใช้งานได้หลายรูปแบบ ใช้เวลาในการเขียนโค้ดน้อย โปรแกรมที่ได้มี Performance สูง (ว่ากันว่า Python 3000 จะมีความเร็วเพิ่มขึ้นอีก 20-30%) จึงไม่ใช่เรื่องแปลกที่ Python จะเป็นภาษาที่ได้รับความนิยมมากขึ้นเรื่อย ๆ

ข้อเสียเปรียบเดียวของ Ruby คือ เป็นภาษาที่ยังใหม่อยู่ จึงยังอาจไม่พร้อมในหลาย ๆ เรื่อง แต่ Community ของ Ruby ก็โตวันโตคืน ทำให้ Ruby ได้รับการพัฒนาอย่างรวดเร็ว และ อาจเทียบชั้นภาษารุ่นพี่อย่าง Java และ Python ได้ในอนาคตอันใกล้

แม้กระนั้นก็ตาม Web-Application ถือเป็นจุดแข็งที่สำคัญที่สุดของ Ruby คุณภาพของ Ruby on Rails อาจทำให้ Ruby เป็นภาษาที่เข้ามาแทนที่ PHP ในอนาคต แต่เรื่องนี้เราคงด่วนสรุปไม่ได้ เพราะขณะนี้มีโปรแกรมจำนวนมากใช้ PHP การเข้ามาแทนที่ PHP ของ Ruby จึงต้องใช้ระยะเวลา และปัจจัยอื่น ๆ อีกมากมาย