北美首頁 | 新聞 | 時尚 | 大陸 | 美國 | 娛樂 | 體育 | 財經 | 圖片 | 移民 | 微博 | 健康
加密貨幣歡迎試用
Value Engine Stock Forecast
ENTER SYMBOL(S)

這個可能打敗Python的編程語言,正在征服科學界

http://finance.sina.com   2020年11月11日 18:26   北京新浪網

  來源:數據實戰派

圖片來源:Unsplash圖片來源:Unsplash

  Julia 語言是近年來科學世界中出現的一匹黑馬。物理學家 Lee Phillips 發表了一篇科普文章,介紹了這種科學計算語言的真正魅力所在。

  最近,我和許多科學家在網上視頻見面了很多次,他們對一個新工具感到興奮。它既不是最新的粒子加速器,也不是超級計算機,而是一種年輕的計算機語言 ——Julia。

  不同的計算機語言擅長的工作也不一樣,有的運行速度很快,有的則更容易開發和部署,有的擁有龐大的生態系統和庫,有的則適用於解決特定問題。

  對於需要模擬氣候變化或核聚變的科學家來說,目前的主流語言是 Fortran。它的編譯器可以充分利用大型超級計算機的強大性能。而對於數據科學家來說,Python 才是最受青睞的語言,因爲它擁有豐富的生態系統,強大的交互性和快速的開發週期。

  六年前,我撰文描寫了 Fortran 在科學計算領域的地位,並與其他幾種語言進行了比較。在文章結尾處我曾預測:十年後,一種名爲 Julia 的新語言很可能取而代之,成爲科學家在解決大規模數字計算問題時更願意使用的語言。

  我的預言不是很準確,因爲 Julia 只用了大約一半的時間,就接近了這一目標。

  通過近年與許多科學家的交流,我確信,Julia 在業界掀起了新的熱情。不過,當年分析它的潛力時,我還不明白爲什麼這種語言會如此受歡迎。

  當時,我的評估是基於 Julia 獨特的便捷語法與出色性能。儘管 Julia 1.0 正式版尚未發佈,但整個社區已經非常興奮。

  Julia 似乎已經解決了 “兩語言問題”(two-language problem),這是 Python 等解釋性語言用戶經常面臨的難題。用 Python 編寫一個程序,雖然可以享受它的便捷語法和交互性,但當計算規模擴大到一定程度,程序的運算速度就會放慢很多。這是 Python 語言本身的侷限性。

  對於大型的仿真模擬運算來說,由於數據量過於龐大,程序的運行速度至關重要,因此研究人員不得不用 C 之類的語言再重寫一個一樣的程序,以提升實際應用時的運行速度。可是速度上來之後,他們在後續研究中又要同時維護和更新兩種語言的代碼。“兩語言問題” 由此而生。

  Julia 自誕生起就以解決 “兩語言問題” 作爲使命,以此吸引科學家和其他人來學習該語言,不過這並不是它唯一令人興奮的地方。

  以今年的 JuliaCon 大會爲例,普通的計算機會議大多圍繞編程、編譯器、算法和優化等計算機科學主題展開。雖然 JuliaCon 上也有這些,但更多的是圍繞科學研究課題,比如流體力學、語言處理、大腦成像等等。這些演講題目給人一種走進了科學研究大會的錯覺。

  這種百花齊放的情況得益於 Julia 編程社區的開放態度,每個人的代碼都可以在 GitHub 上找到。如果有人希望使用現成的算法,從幫助文檔到代碼註釋,都可以拿到最新版本。

  這與絕大多數年齡較大的科學家所熟悉的氛圍完全不同:在過去,科研代碼幾乎不會離開實驗室。

  Julia 社區正是以大規模的協作和代碼共享爲基石。

  解決 “表達問題”

  “表達問題”(Expression Problem)是計算機語言設計研究中的常見概念。它是計算機科學的分支研究領域,人們對它的含義和解釋往往十分抽象,並且依賴於專業術語。

  如果想要更好地理解這個概念,我們或許可以將其類比成烹飪。

  首先我們要明確一些計算機科學術語,包括函數 / 程序、數據類型和庫 / 模塊 / 包。

  簡單來說,函數 / 程序指的是 “獲取輸入值,對其進行處理,最後產生輸出值” 的過程。數據類型是數字、字符或其他信息的集合,這些信息有各式各樣的結構,可以由函數操控。庫 / 模塊 / 包則是函數的集合,還包括函數使用的數據類型的描述。

  接下來我們開始類比。

  如果你知道食譜和烹飪是什麼意思,這個類比就很好懂。我們可以將庫 / 模塊 / 包視爲市面上出售的 “食譜書”,函數 / 程序就是 “製作菜餚的完整過程或技術”,而數據類型就是需要用到的 “食材或配料”。

  現在想象一下食譜的內容。一般來說,食譜都是以不同菜品爲分類,比如炒菜實際上細分爲如何炒洋蔥,如何炒蝦等等。每一道菜的步驟不同,因爲它們使用的食材或配料不同。這些食材和配料表也是食譜的一部分。

菜品烹飪需要特定食材和配料。(圖片來源:Lee Phillips)菜品烹飪需要特定食材和配料。(圖片來源:Lee Phillips)

  如果我們要添加一道新菜,那隻需要囊括所有涉獵到的食材或配料就可以了,其他現有的菜品都不需要任何改動 —— 新菜不會讓舊菜失效。

添加新菜不會影響舊菜。(圖片來源:Lee Phillips)添加新菜不會影響舊菜。(圖片來源:Lee Phillips)

  但如果我們想加入新的配料或食材怎麼辦?比如現有菜品製作過程中沒有用到魚,那麼我們就需要修改現有的製作過程。

但要添加新的食材,就要改變現有菜譜。(圖片來源:Lee Phillips)但要添加新的食材,就要改變現有菜譜。(圖片來源:Lee Phillips)

  不過,組織食譜書的方法有很多,另一種方法是圍繞食材來組織書譜,而不是烹飪方法。每個食材,都會有配套的烹飪技術和方法。就像下圖所示:

以食材爲核心來組織菜譜。(圖片來源:Lee Phillips)以食材爲核心來組織菜譜。(圖片來源:Lee Phillips)

  在這種情況下,烹飪技術就不再是獨立存在的,而是與所使用的食材相關聯。如果要新添加魚作爲新的食材,就可以編寫一個新的魚的製作方法,與現有的魚類烹飪方法整合在一起。

這樣一來,添加新食材就不用改變現有菜譜。(圖片來源:Lee Phillips)這樣一來,添加新食材就不用改變現有菜譜。(圖片來源:Lee Phillips)

  但如果想添加一種新烹飪技術呢?比如如何使用攪拌機?

  在不更改現有工作的情況下,我們沒有辦法實現。因爲現有技術已經綁定在食材上,新烹飪技術必然會改變食材的製作方法。

  這兩種食譜的組織方式類似於兩種計算機語言類型。圍繞烹飪過程的食譜書是 “面向過程的語言”,而圍繞食材的食譜書則是 “面向對象的語言”。兩種語言各有千秋。

  這其實就是 “表達問題”:無論哪種語言,都存在擴展軟件(食譜)的障礙。在重用和組合現有代碼時,能否不更改現有已存在的軟件包至關重要。

  如果你覺得前面的類比還不夠清楚,接下來這一節還有另一種更直觀的解釋。

  引入“多重調度”

  顯而易見的是,若有一種無論什麼情況下都不用更改已有內容的方式來組織食譜,就可以獲得極大的擴展自由度,那將是一個很大的優勢。

  與其嚴格遵照製作過程和食材來組織食譜,不如採用一種更通用且靈活的方法。如下圖所示:

看起來雜亂的新菜譜組合方式,允許更大的自由度。(圖片來源:Lee Phillips)看起來雜亂的新菜譜組合方式,允許更大的自由度。(圖片來源:Lee Phillips)

  這張圖片顯示了方法與食材的自由關聯,誰都不是另外一個的附屬品。但這不代表能隨機組合無關的方法,而是要基於現有方法創建變種,並與不同的食材配套。

  舉個例子,我們現有的食譜書包含了炸雞的烹飪過程。如果想添加煎魚的過程,也不需要重新編寫,只需要指導讀者用炸雞的方式煎魚,但要使用更高的溫度,並且將配料更早的剔除。

  另一種審視三種思維模式的方法是想一想 “食譜的目錄”。

  在 “面向功能” 的版本中,目錄可能是這樣的:

  - 第一章:煎炸

  雞

  魚

  - 第二章:水煮

  雞

  魚

  在這種情況下,添加新功能只需要新開一章,但添加新的食材(比如雞蛋)需要修改現有章節:在第一章添加煎蛋,第二章添加水煮蛋等等。

  在 “面向對象” 的版本中,目錄可能是這樣的:

  - 第一章:雞

  煎炸

  水煮

  - 第二章:魚

  煎炸

  水煮

  在這種情況下,添加新食材只需要新開一章,但添加新的烹飪方法(比如烤)需要修改現有章節:在第一章添加烤雞,第二章添加烤魚等等。

  至於第三種方法,秉承可最大程度擴展食譜的思想,目錄可能是這樣的:

  - 第一章:炸雞

  - 第二章:水煮雞

  - 第三章:炸魚

  - 第四章:水煮魚

  很顯然,無論是食材還是烹飪技術,都能作爲新章節自由添加到書中,無需修改任何現有章節:第五章烤雞,第六章烤魚等等。

  與前兩個版本相比,第三種模式似乎沒有組織性。

  但在實際操作中,烹飪方法和食材之間的關係可以成爲庫結構的一部分。在食譜類比的語境中,我們可以想象雞和魚是肉的子集,草莓和櫻桃是紅色水果的子集,而煎炒和水煮則是更大的通用烹飪方法的變體,以此類推。

  這種思維模式是解決 “表達問題” 的一種嘗試。這在語言設計中也被稱爲 “多重調度”,指的是基於要應用的所有數據類型的類型自動選擇方法。

  “多重調度” 是 Julia 解決 “表達問題” 的方法,也是其核心組織原則,因此 Julia 既不是面向對象的,也不是面向功能的。它採用的解決方法比兩者更強大,更通用。這意味着 Julia 在混合和使用庫方面更加自由。

  工具的重要性

  Julia 不是第一個嘗試解決 “表達問題” 的語言,也不是第一個用到 “多重調度” 的語言。擁有該功能的 Common Lisp 語言已經誕生 40 年,Perl 等語言的最新版本也擁有該功能。用戶已經肯定了 “多重調度” 在編寫和擴展庫方面的便利性。

  但 Julia 與它們的區別在於,Julia 是圍繞 “多重調度” 設計的,而其他語言只是將其作爲可選項,並且會帶來性能損失。比如 Julia 的 “多重調度” 允許其更靈活和自然地表達數學思維,其社區代碼重用量讓語言設計者都感到驚訝。

  不過想在科學界立足,有了上述優勢還不夠。Julia 之所以受到了大量關注,還在於它將 “多重調度” 和其他特性相結合,比如快速上手的免費高質量代碼和非常快的運算速度,對需要大量數字運算的科學家非常有吸引力。

  斯坦福大學教授 Mykel Kochenderfer 使用 Julia 設計了避免飛機碰撞的系統,該系統已成爲國際標準。他表示,Julia 不僅 “是高級的,可被解釋的語言,而且它的運行速度也與高度優化的 C ++ 代碼一樣快。”

  Julia 還具有表達力強,易於閱讀的語法,尤其是在處理數組時。它爲數字算法的並行處理提供了一條快速通道。它具有 Unicode 時代的設計優點,使其在表述數學公式時更像真正的數學。

  下面這幅圖片是 Julia 程序中的實際代碼,使用了專門爲 Julia 語言設計的字體。

Julia 語言的數學公式表達。(圖片來源:Lee Phillips)Julia 語言的數學公式表達。(圖片來源:Lee Phillips)

  Julia 的這些特性在早期就吸引了許多科學家,甚至在 “多重調度” 的特殊優勢引發關注之前,就已經吸引了大量用戶。

  而我從中所學到的核心思想是:工具很重要。這就好比,畫家作畫時要選好符合作品風格的畫筆和顏料,而作曲家腦海中的音律必須與樂器和表演者的技巧相吻合。

  作爲一個編程工具,Julia 之於科學家也是一樣。它能擴展科學家在有限時間內能夠完成的任務,幫助其實現未曾想象過的想法。

Bookmark and Share
|
關閉
列印