algorithm  programming  

Jan 12, 2018 • Michael Chen

筆者最近在國內某程式討論區上看到一則有關資料結構的問題,原樓主是某個資訊科系的學生,因為對資料結構的實作不熟而苦惱。原先該網友使用 C 語言,而有些網友建議原 po 改用 Python,這時候引起正反兩方的一番論戰,筆者在這裡就不重覆論述其過程。其實重點並不在於要不要用 Python,而是為什麼要 (或不要) 用 Python。

首先,程式語言並不是像江湖武術般,非黑即白、有我沒你,另投他門就是罪該萬死。在某個時機點,A 語言可能會是最佳解 (sweet spot),但在另一個時間點,同樣的語言卻顯得殺雞用牛刀。TensorFlow 表面上是 Python 套件庫,但內部是由 C++ 撰寫,再透過 C 提供 Python (和其他高階語言) 的接口。同樣地,LibXML2 本身以 C 寫成,在 Python 包成 lxml,在 Ruby 則包成 Nokogiri。我們會用 C (或 C++) 寫其他高階語言的延伸套件,但不會直接用這兩種語言寫命令稿,因為不同語言有其合適的使用時機。

那麼,我們為什麼會用 Python (或 Ruby 或其他高階語言) 實作資料結構和演算法呢?即使演算法正確,用 Python 實作的實用性相對偏低。不過,我們仍然可以看到一些用 Python 實作資料結構或演算法的書,像是 Data Structure and Algorithmic Thinking with Python (CareerMonk Publications, 2015) 等;良葛格也在其網站上用 C、Java、Python、Ruby、JavaScript 等多種語言展示相同的演算法,表示英雄所見略同。演算法是讓電腦程式更有效率的方法論,本身和特定的程式語言無關,不論是 Python、Ruby 或其他的高階語言,都可拿來做為練習的工具。使用 Python 這類較高階的語言,可以減少因語言本身的特性所造成的錯誤,專注在抽象思考上。

不過,如果自己的工作和資訊相關,最好還是要學一下 C (或 C++)。雖然用 Python 或 Ruby 或其他高階語言寫程式很舒服愉悅,我們有時還是會碰到一些效能瓶頸的部分,這些部分還是得回頭用 C (或 C++) 來寫。即使不直接用 C 寫程式,有一些 C 的知識還是會有幫助,像是在安裝一些高階語言的延伸模組時,背後實際上仍是某些 C (或 C++) 所寫的程式在運作著,這時候相關的背景知識就會有些幫助。即使使用像 Rust 這種新興語言,要和其他語言合作時,仍需提供 C 的接口,這時就會間接用到 C 的知識。

由於以 C (或 C++) 撰寫程式需要程式設計者的專注和自律,後來有一些新興的編譯語言試圖簡化這些苦工,像是先前的 D 或是近年來的 Go (golang) 和 Rust。這些語言並沒有取代 C,仍然提供 C 的接口;但以這些語言撰寫程式,會比直接用 C/C++ 來得簡單。在這些語言中,Go 由於簡潔的設計和良好的工具鏈,在國外相當地風行;而 D 和 Rust 各有一些支持者。程式語言試圖在效率和易用間取得一個最佳的平衡點,每個語言的設計哲學不同,使其使用情境相異。

使用那種語言實作資料結構和演算法沒有絕對的對錯,而要想想為什麼在這個當下要用 A 語言而非 B 語言。當自己清楚箇中緣由後,就不需落入網路上的口水戰了。