使用Java8的Nashorn彌補Node.js密集計算的缺陷
NodeJS帶來的原生非同步併發與事件驅動程式設計模型得到認可,但是因為其單執行緒緣故,不能簡單方便地從事密集計算,而java優勢是多執行緒併發,Java 8又引入了Lambda表示式,使得Java多執行緒併發在處理高CPU負載的計算上既強大又方便,那麼我們是否對於Javascript中那些密集計算,比如對集合中的map操作,或聚合操作reduce使用Java實現呢?
答案是可以的,利用Java8的Javascript引擎 Nashorn。比如我們可以將Js如下的lambda在JVM中實現:
Nashorn是用來替代原來Java中的Javacript直譯器Rhino, 執行JS速度大大提升,能夠使用V8s環境,下面看看如何編譯lambda表示式。
不同於Java 和Scala 編譯器,是將檔案編譯成持久檔案,如.class檔案等,Nashorn是在記憶體中編譯,然後將位元組碼直接傳遞到JVM,Java 8使用invokerDynamic來連線Lambda函式程式碼。
invokerDynamic是在Java 7中加入允許程式設計師寫動態語言,然後決定在執行時如何連線這些程式碼。
對於Java和Scala語言,編譯器是在編譯時間決定哪個方法被呼叫,執行時是透過標準的ClassLoader來尋找相應的類,即使像方法過載解決也是編譯時間實現的。
對於動態語言,如js,靜態的解決辦法就不適用了,當我們在Java中說obj.foo()時,其實是obj有一個類的方法為foo(),而JS執行時是依賴被obj引用的實際物件,這對於靜態語言是一個夢魘,因為編譯和執行是分開的,編譯時連線到這個物件但是卻沒有執行。但是invokeDynamic可以做到。
invokeDynamic能夠推遲這種聯動到執行時間,這樣在執行時它能指導JVM呼叫哪個方法。靜態語言和動態語言在這點上是雙贏的。JVM得到要連線的實際方法,然後最佳化執行。
Nashorn也是這樣高效地實現連線,下面看個例子可以瞭解如何工作的,下面是返回JS陣列值:
invokedynamic 0 "dyn:getProp|getElem|getMethod:prototype":(Ljava/lang/Object;)Ljava/lang/Object;
Nashorn要求JVM在執行傳遞給它這個字串,作為交換,它會返回一個方法的一個處理器,用於接收物件和返回一個,只要JVM得到這個方法的一個處理器,它就能連線。
詳細流暢比較複雜,可見文章:Java 8: Compiling Lambda Expressions in The New Nashorn JS Engine
答案是可以的,利用Java8的Javascript引擎 Nashorn。比如我們可以將Js如下的lambda在JVM中實現:
ScriptEngineManager manager = new ScriptEngineManager(); ScriptEngine engine = manager.getEngineByName("nashorn"); String js; js = "var map = Array.prototype.map \n"; js += "var names = [\"john\", \"jerry\", \"bob\"]\n"; js += "var a = map.call(names, function(name) { return name.length() })\n"; js += "print(a)"; engine.; <p class="indent"> |
Nashorn是用來替代原來Java中的Javacript直譯器Rhino, 執行JS速度大大提升,能夠使用V8s環境,下面看看如何編譯lambda表示式。
不同於Java 和Scala 編譯器,是將檔案編譯成持久檔案,如.class檔案等,Nashorn是在記憶體中編譯,然後將位元組碼直接傳遞到JVM,Java 8使用invokerDynamic來連線Lambda函式程式碼。
invokerDynamic是在Java 7中加入允許程式設計師寫動態語言,然後決定在執行時如何連線這些程式碼。
對於Java和Scala語言,編譯器是在編譯時間決定哪個方法被呼叫,執行時是透過標準的ClassLoader來尋找相應的類,即使像方法過載解決也是編譯時間實現的。
對於動態語言,如js,靜態的解決辦法就不適用了,當我們在Java中說obj.foo()時,其實是obj有一個類的方法為foo(),而JS執行時是依賴被obj引用的實際物件,這對於靜態語言是一個夢魘,因為編譯和執行是分開的,編譯時連線到這個物件但是卻沒有執行。但是invokeDynamic可以做到。
invokeDynamic能夠推遲這種聯動到執行時間,這樣在執行時它能指導JVM呼叫哪個方法。靜態語言和動態語言在這點上是雙贏的。JVM得到要連線的實際方法,然後最佳化執行。
Nashorn也是這樣高效地實現連線,下面看個例子可以瞭解如何工作的,下面是返回JS陣列值:
invokedynamic 0 "dyn:getProp|getElem|getMethod:prototype":(Ljava/lang/Object;)Ljava/lang/Object;
Nashorn要求JVM在執行傳遞給它這個字串,作為交換,它會返回一個方法的一個處理器,用於接收物件和返回一個,只要JVM得到這個方法的一個處理器,它就能連線。
詳細流暢比較複雜,可見文章:Java 8: Compiling Lambda Expressions in The New Nashorn JS Engine
相關文章
- pat—結構體排序(用map彌補struct缺陷)結構體排序Struct
- 密集計算場景下的 JNI 實戰
- AI是如何彌補技術鴻溝的?AI
- java8 新特性 v8 nashorn 引擎(五)Java
- opencv使用convexityDefects計算輪廓凸缺陷OpenCV
- CPU-bound(計算密集型) 和I/O bound(I/O密集型)
- 亞馬遜的向後工作法可以彌補敏捷不足 -hbr亞馬遜敏捷
- java8平行計算Java
- 填坑利器?Redis如何彌補傳統MySQL架構的不足RedisMySql架構
- 計算機中的補碼與java取反運算計算機Java
- “鑽石的缺陷”為量子計算機提供完美介面VG計算機
- 【object C】ObjectC中如何彌補switch引數不能為字串的方法Object字串
- “彌補”sqlplus的游標移動與命令回顯功能SQL
- 【1分鐘知識點】利用「佔位塊」彌補 space-between 的不足
- 不能用谷歌翻譯的痛,就用這些翻譯神器來彌補吧谷歌
- Javascript的10個設計缺陷JavaScript
- “Node.js”為何不適合CPU密集型應用?Node.js
- 計算機補碼儲存計算機
- 計算機原碼, 反碼,補碼的介紹計算機
- DDD彌補了瀑布和敏捷兩個方法的不足之處! - 47 North Labs敏捷
- Java8的Stream API使用JavaAPI
- 權威報告密集背書百度,雲端計算的「雲+AI」大戰開啟AI
- 關於vue的使用計算屬性VS使用計算方法的問題Vue
- 【虹科分享】針對終端的Defender:Morphisec彌補Windows10安全防護Windows
- Java 8 的 Nashorn 指令碼引擎教程Java指令碼
- dubbo~全域性異常攔截器的使用與設計缺陷
- Java8 學習之計算日期相差天數Java
- java8之ForkJoin框架的使用Java框架
- 淺談java8中的流的使用Java
- [精選]當PHP遇上Go會怎樣?GO語言彌補了PHP的不足,然後。。。PHPGo
- 如何利用員工個人資料監控來彌補安全漏洞
- 彌補效能鴻溝,傲騰在企業應用中加速普及
- 深入理解計算機中的原碼、補碼、反碼計算機
- 【計算機本科補全計劃】C++ Primer:String Vector標準庫及迭代器的使用計算機C++
- dubbo~全域性異常攔截器的使用與設計缺陷~續
- 筆記:PostgreSQL 、Node.js 、函式計算筆記SQLNode.js函式
- 計算機為什麼要用補碼計算機
- 計算機原理基礎-原反補計算機