自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

Scala和Erlang,以及多核主導(dǎo)的未來(lái)

開(kāi)發(fā) 后端
這篇文章于08年發(fā)布在Infoq上,在過(guò)了一年之后,這篇文章中所談到的東西仍然很有參考價(jià)值。如果您還沒(méi)有閱讀過(guò)這篇文章,那就再看一看多核時(shí)代為何能成為Scala和Erlang的天下吧。

未來(lái)注定是多核的世界,問(wèn)題在于如何去解決多核的危機(jī)。Scala和Erlang是兩門(mén)渴望成為其解決方案的語(yǔ)言,但它們也有些許的不同。那么它們所采取的方式各有什么利弊呢?

引入問(wèn)題

摩爾定律已經(jīng)改變了。我們不再獲得和以前一樣的時(shí)鐘頻率增長(zhǎng),取而代之,我們得到了更多的(CPU)核心。今天,也許你的筆記本都已經(jīng)是雙核的了。

為了利用多核的特性,應(yīng)用程序需要支持并發(fā)。如果你的客戶買(mǎi)了一臺(tái)八核的機(jī)器,要向他們解釋清楚正常情況下應(yīng)用程序只會(huì)用到12%的CPU能力將是一件費(fèi)時(shí)費(fèi)力的事,即便該機(jī)器是為該應(yīng)用量身定制的。

在未來(lái),情況可能變得更糟。你的順序執(zhí)行代碼不僅不會(huì)跑得更快,甚至有可能實(shí)際上跑得更慢。其原因在于,你獲得越多的核心,由于功耗和散熱的影響,每個(gè)核心就會(huì)更慢。幾年之后,英特爾就會(huì)給我們帶來(lái)32核的CPU,按這種趨勢(shì),在我們不知不覺(jué)之中數(shù)千核的CPU就會(huì)出現(xiàn)。但每個(gè)核心都會(huì)比現(xiàn)在的核心慢很多。

并發(fā)代碼

一個(gè)顯見(jiàn)的解決途徑就是編寫(xiě)(或重寫(xiě))軟件以支持并發(fā)。最常見(jiàn)的方式莫過(guò)于使用線程,但大多數(shù)開(kāi)發(fā)者都認(rèn)為基于線程的應(yīng)用編寫(xiě)起來(lái)特別的困難。死鎖,餓死以及競(jìng)爭(zhēng)條件對(duì)大多數(shù)并發(fā)開(kāi)發(fā)者來(lái)說(shuō)都是太熟悉的概念了。Erlang和Scala都大大減輕了這種痛苦。

語(yǔ)言概覽

Scala常被看作是下一個(gè)主要的JVM語(yǔ)言。它結(jié)合了面向?qū)ο缶幊痰姆妒胶秃瘮?shù)式編程的范式,與Java相比有著更簡(jiǎn)潔的語(yǔ)法,它是靜態(tài)類(lèi)型的,有著跟Java一樣或者有時(shí)候更快的運(yùn)行速度。有太多的理由值得去認(rèn)真探索一下Scala。

Erlang是一門(mén)為健壯性而生的語(yǔ)言,由于它的設(shè)計(jì),它自然又是一門(mén)有著極好伸縮性的語(yǔ)言。它比Java歷史更早,但卻常被看作引領(lǐng)未來(lái)并發(fā)的語(yǔ)言。它是一門(mén)動(dòng)態(tài)類(lèi)型的函數(shù)式語(yǔ)言,有著一些非凡的系統(tǒng)正常運(yùn)行時(shí)間的成功例子。

爭(zhēng)論核心

那么Scala與Erlang爭(zhēng)論的到底是什么呢?說(shuō)到底,就是性能表現(xiàn)與伸縮能力,但這爭(zhēng)論也包括了其它像風(fēng)格,語(yǔ)言特性以及庫(kù)支持等等。這場(chǎng)爭(zhēng)論開(kāi)始于Ted Neward有一次無(wú)心的給出了他對(duì)幾種語(yǔ)言的看法,并稱(chēng)“[Erlang]在其自己解釋器上運(yùn)行事實(shí)上[是]很差的”。

Steve Vinoski與Ted于是展開(kāi)了幾輪爭(zhēng)論,但這一討論很快轉(zhuǎn)移到了更多的博客上,爭(zhēng)論的焦點(diǎn)也轉(zhuǎn)變成了Scala與Erlang之間那些有趣的差異和共同點(diǎn)。我們將總結(jié)每個(gè)有意思的論點(diǎn)并給出每種語(yǔ)言的利弊,并表達(dá)對(duì)一些問(wèn)題的各種不同看法。

可靠性

Steve Vinoski就Ted所發(fā)表的帖子進(jìn)行了回應(yīng),給出了他對(duì)于“Erlang在其自己解釋器上運(yùn)行”的感受:

事實(shí)上,Erlang在其自己解釋器上運(yùn)行得,很好很強(qiáng)大;如若不然,不可能有如此好的可靠性,它將只是又一個(gè)面向并發(fā)的有趣但卻無(wú)用的語(yǔ)言實(shí)驗(yàn)而已。

Steve談到這個(gè)問(wèn)題,就算一個(gè)語(yǔ)言本身可靠,它所依賴(lài)的基礎(chǔ)也必須可靠才行。因?yàn)镋rlang從骨子里就是為可靠性而設(shè)計(jì)的,從而支持并發(fā),所以它不會(huì)受到一些并發(fā)性常見(jiàn)問(wèn)題的影響,這主要是底層庫(kù)包在并發(fā)環(huán)境下運(yùn)行很好。

另一方面,Scala是站在JVM之上的,所以一個(gè)重要賣(mài)點(diǎn)在于可潛在地使用所有現(xiàn)成的Java代碼。然而,大部分的Java代碼并非專(zhuān)為并發(fā)而設(shè)計(jì)的,使用Scala代碼時(shí)要將此考慮進(jìn)去。

輕量級(jí)進(jìn)程

要運(yùn)行大規(guī)模并發(fā)應(yīng)用,你需要大量的并行執(zhí)行。這可以通過(guò)幾種方式達(dá)到。使用線程是一種常見(jiàn)的方式,使用進(jìn)程又是另一種。其區(qū)別之處在于,線程與其它線程之間共享內(nèi)存,而進(jìn)程是相互獨(dú)立的。這意味著線程需要像互斥信號(hào)這樣的鎖機(jī)制,防止兩個(gè)線程在同一時(shí)間對(duì)同一內(nèi)存進(jìn)行操作,但進(jìn)程不會(huì)受此問(wèn)題影響,相反是使用一些消息傳遞機(jī)制來(lái)跟其它的進(jìn)程間通信。但進(jìn)程在性能和內(nèi)存方面的代價(jià)是昂貴的,這正是人們就算知道基于線程的并發(fā)是一種極復(fù)雜的編程模型也寧愿選擇它的原因。

Steve Vinoski這樣寫(xiě)到:

提供互不共享的輕量級(jí)進(jìn)程架構(gòu)將使得大規(guī)模并發(fā)能力變得十分容易,但這并不意味著一旦你設(shè)計(jì)好了,剩下的就只是編程的工作那么簡(jiǎn)單。

Erlang采取了這樣的并發(fā)方式。一個(gè)Erlang進(jìn)程是非常輕量化的,Erlang應(yīng)用常常擁有成千上萬(wàn)的線程甚至更多。

Scala通過(guò)基于事件的Actor從另一方面達(dá)到了同樣的效果。Yariv Sadan解釋說(shuō):

Scala有兩種類(lèi)型的Actor:基于線程或是基于事件?;诰€程的Actor在重量級(jí)的OS線程內(nèi)部執(zhí)行。它們從不相互阻塞,但每個(gè)VM上可伸縮的Actor不會(huì)多于幾千個(gè)?;谑录腁ctor是簡(jiǎn)單的對(duì)象。它們是十分輕量化的,并且,像Erlang進(jìn)程一樣,因此它們可以在一臺(tái)現(xiàn)代的機(jī)器上數(shù)以百萬(wàn)計(jì)的產(chǎn)生。

Yariv解釋到,盡管如此,這里面也還是有一些區(qū)別的:

與Erlang進(jìn)程的區(qū)別之處在于,每個(gè)OS線程內(nèi)部,基于事件的Actor是順序執(zhí)行的并且使用沒(méi)有強(qiáng)占式調(diào)度算法。這使得一個(gè)基于事件的Actor可能在很長(zhǎng)一段時(shí)間內(nèi)阻塞其OS線程(甚至是無(wú)限的)。

不可變性

Erlang是一門(mén)函數(shù)式語(yǔ)言。這意味著其數(shù)據(jù)是不可變的,像Java的String一樣,并且沒(méi)有副作用帶來(lái)的風(fēng)險(xiǎn)。對(duì)數(shù)據(jù)的任意操作會(huì)產(chǎn)生一個(gè)該數(shù)據(jù)新的修改后的版本,但原數(shù)據(jù)仍然不變。在談到健壯性的時(shí)候,不可變性是其需要高度注意的一個(gè)因素,因?yàn)闆](méi)有代碼可以無(wú)意間修改其它代碼依賴(lài)的數(shù)據(jù),但從并發(fā)的觀點(diǎn)來(lái)看,不可變性也是一個(gè)十分重要的特性。如果數(shù)據(jù)不可變,其被兩個(gè)并行執(zhí)行路徑更改的風(fēng)險(xiǎn)就不存在,因?yàn)闆](méi)有辦法改變它且不需要保持同步,所以數(shù)據(jù)可以被拷貝到其它機(jī)器上。

因?yàn)镾cala構(gòu)建在JVM之上,結(jié)合了面向?qū)ο蠛秃瘮?shù)式方法的特點(diǎn),它不具備像純函數(shù)式語(yǔ)言的不可變性的保證。然而,在Yariv日志的評(píng)論部分,Yariv和David Pollack就這兩門(mén)語(yǔ)言之間的差別展開(kāi)了一場(chǎng)有趣的討論。David,Scala Web框架Lift的作者,給出了他對(duì)于不可變性的看法:

不可變性 —— Erlang強(qiáng)制了這一點(diǎn),而且你幾乎無(wú)法繞過(guò)它。但是,與強(qiáng)制一個(gè)單一類(lèi)型相比,你可以用Scala神奇強(qiáng)大的類(lèi)型系統(tǒng)的剩余部分去交換。我在進(jìn)行Scala Actor編碼時(shí)使用不可變數(shù)據(jù),而讓Scala的類(lèi)型系統(tǒng)負(fù)責(zé)其它類(lèi)型。
Yariv問(wèn)到:

只發(fā)送不可變類(lèi)型難道不是一個(gè)重大限制嗎?這意味著,例如,你不能從Hibernate裝載一個(gè)簡(jiǎn)單的bean并將它發(fā)送給其它Actor。
David回答到:

我曾基于Scala的Actor構(gòu)建個(gè)多個(gè)生產(chǎn)系統(tǒng)。實(shí)際上對(duì)于不可變性問(wèn)題并沒(méi)有多少工作需要處理。你只需要將你的相關(guān)類(lèi)(消息)定義為不可變的,其它的就不用管了。

類(lèi)型系統(tǒng)

Erlang是動(dòng)態(tài)類(lèi)型的,而Scala是靜態(tài)類(lèi)型的并且相比Java有著更強(qiáng)的類(lèi)型系統(tǒng)。然而,與Java相比最大的一個(gè)區(qū)別是Scala可以類(lèi)型推斷。這意味著你可以省掉大部分的類(lèi)型注解,使得代碼更加干凈而編譯器照樣會(huì)做所有的檢查。

關(guān)于動(dòng)態(tài)與靜態(tài)系統(tǒng)之間孰是孰非的爭(zhēng)論看來(lái)永遠(yuǎn)也不會(huì)停止,但Erlang和Scala之間卻有著顯而易見(jiàn)的區(qū)別。

尾遞歸或是循環(huán)

Yariv又提到:

函數(shù)式編程與遞歸從來(lái)都是形影不離的。實(shí)際上離開(kāi)了尾遞歸你很難寫(xiě)出有用的Erlang程序,那是因?yàn)镋rlang沒(méi)有循環(huán)——它對(duì)一切都使用遞歸(這在我看來(lái)是一件好事 :))。
這顯然使得Erlang與Scala產(chǎn)生了很大差別。Scala提供了很多更傳統(tǒng)的迭代,但David Pollack并沒(méi)看出在這種環(huán)境下尾遞歸有什么優(yōu)勢(shì):

尾遞歸——對(duì)基于事件的Actor來(lái)說(shuō)根本不是什么問(wèn)題。
如此說(shuō)來(lái),這僅僅有關(guān)你的偏愛(ài)和風(fēng)格罷了。

熱交換代碼

由于Erlang是為可靠性而生的,熱交換代碼(運(yùn)行時(shí)替換代碼)是其內(nèi)建的天性。

JVM對(duì)熱交換代碼有所支持。類(lèi)可以被改變,但由于其靜態(tài)的類(lèi)型系統(tǒng),其方法簽名是不可改變的——只有其內(nèi)容可以改變。雖然有第三方工具致力于此,也有框架(提倡以一種使運(yùn)行時(shí)更方便交換類(lèi)的編程風(fēng)格書(shū)寫(xiě)代碼),但就算運(yùn)行在JVM上,如何進(jìn)行交換仍是取決于你的Scala Actor是如何構(gòu)建的。Jonas Bonér就此給出了一個(gè)詳盡的例子。

總結(jié)

Scala和Erlang都是致力于解決多核危機(jī)的語(yǔ)言。它們來(lái)自不同的背景和年代,因此對(duì)待某些問(wèn)題的方式也不盡相同,然而在許多方面它們的共識(shí)大于分歧,至少在并發(fā)性上如此。

Erlang已經(jīng)有著數(shù)十年的歷史,并且已經(jīng)在許多關(guān)鍵的真實(shí)系統(tǒng)中證明了自己。其不足之處在于它有一點(diǎn)像一個(gè)孤島,最近的多語(yǔ)言編程的趨勢(shì)似乎對(duì)Erlang社區(qū)影響不大。

另一方面,Scala是同一類(lèi)型應(yīng)用的新生兒。一些真實(shí)應(yīng)用即將誕生,并且一些公司將未來(lái)押在了上面。Scala相對(duì)Erlang的最大優(yōu)勢(shì)在于,它運(yùn)行在JVM之上并且可以利用所有現(xiàn)成Java代碼、框架和許多工具。話雖如此,這種強(qiáng)大的能力也要求了更大的責(zé)任,因?yàn)榇蟛糠諮ava代碼不可能自動(dòng)適應(yīng)Scala的Actor模型。

對(duì)于主流語(yǔ)言無(wú)法幫開(kāi)發(fā)者解決的壓力越來(lái)越大的問(wèn)題,兩種語(yǔ)言都對(duì)提供了相似的解決途徑。希望你在讀完這篇爭(zhēng)論總結(jié)之后,能更清楚哪種語(yǔ)言更適合你的特殊要求,并對(duì)其深入了解。

未來(lái)是多核的。Scala和Erlang將會(huì)越來(lái)越流行。

【編輯推薦】

  1. Scala編程語(yǔ)言
  2. 一位Twitter工程師的Scala探秘之旅
  3. Erlang面向分布與并發(fā)的編程語(yǔ)言
  4. Erlang十分鐘快速入門(mén)
  5. 因并發(fā)而生 因云計(jì)算而熱:Erlang專(zhuān)家訪談實(shí)錄
責(zé)任編輯:yangsai 來(lái)源: Infoq
相關(guān)推薦

2010-01-25 13:08:48

2022-09-08 19:09:02

人工智能語(yǔ)音命令

2023-05-19 16:45:15

人工智能AI

2013-07-08 10:15:46

系統(tǒng)虛擬化 Containers

2010-05-12 10:04:49

云計(jì)算

2009-09-09 10:50:55

Scala例子Scala與Java

2009-08-26 10:39:01

Scala和Cloju

2022-09-08 14:19:34

人工智能智能家居智能家電

2009-07-09 16:27:14

2022-06-08 11:22:12

5G邊緣技術(shù)

2018-02-28 14:00:32

云計(jì)算混合云多云

2009-08-12 13:41:23

Java并發(fā)編程并行編程多核

2014-03-25 12:06:21

IBM

2009-08-02 16:54:14

刀片服務(wù)器數(shù)據(jù)中心節(jié)能

2009-06-16 17:54:38

Scala類(lèi)語(yǔ)法語(yǔ)義

2023-08-25 14:13:28

生成式AI人工智能

2010-08-25 11:54:46

LTE4G

2010-08-16 10:20:59

李開(kāi)復(fù)移動(dòng)互聯(lián)網(wǎng)電子商務(wù)

2010-04-16 11:15:50

2013-12-18 17:29:10

多核并行
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)