Nashorn是什么

Nashorn,发音“nass-horn”,是德国二战时一个坦克的命名,同时也是java8新一代的javascript引擎--替代老旧,缓慢的Rhino,符合 ECMAScript-262 5.1 版语言规范。你可能想javascript是运行在web浏览器,提供对html各种dom操作,但是Nashorn不支持浏览器DOM的对象。这个需要注意的一个点。

关于Nashorn的入门

主要是两个方面,jjs工具以及javax.script包下面的API:

jjs是在java_home/bin下面自带的,作为例子,让我们创建一个func.js, 内容如下:

1
2
3
4
function f() {
return 1;
};
print( f() + 1 );

运行这个文件,把这个文件作为参数传给jjs

1
jjs func.js

输出结果:2

另一个方面是javax.script,也是以前Rhino余留下来的API

1
2
3
4
ScriptEngineManager manager = new ScriptEngineManager();
ScriptEngine engine = manager.getEngineByName( "JavaScript" );
System.out.println( engine.getClass().getName() );
System.out.println( "Result:" + engine.eval( "function f() { return 1; }; f() + 1;" ) );

输出如下:

1
2
3
jdk.nashorn.api.scripting.NashornScriptEngine
Result: 2
Nashorn VS Rhino

javascript运行在jvm已经不是新鲜事了,Rhino早在jdk6的时候已经存在,但现在为何要替代Rhino,官方的解释是Rhino相比其他javascript引擎(比如google的V8)实在太慢了,要改造Rhino还不如重写。既然性能是Nashorn的一个亮点,下面就测试下性能对比,为了对比两者之间的性能,需要用到Esprima,一个ECMAScript解析框架,用它来解析未压缩版的jquery(大约268kb),测试核心代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
static void rhino(String parser, String code) {
    String source = "speedtest";
    int line = 1;
    Context context = Context.enter();
    context.setOptimizationLevel(9);
    try {
      Scriptable scope = context.initStandardObjects();
      context.evaluateString(scope, parser, source, line, null);
      ScriptableObject.putProperty(scope, "$code", Context.javaToJS(code, scope));
      Object tree = new Object();
      Object tokens = new Object();
      for (int i = 0; i < RUNS; ++i) {
        long start = System.nanoTime();
        tree = context.evaluateString(scope, "esprima.parse($code)", source, line, null);
        tokens = context.evaluateString(scope, "esprima.tokenize($code)", source, line, null);
        long stop = System.nanoTime();
        System.out.println("Run #" + (i + 1) + ": " + Math.round((stop - start) / 1e6) + " ms");
      }
    finally {
      Context.exit();
      System.gc();
    }
  }
  static void nashorn(String parser, String code) throws ScriptException,NoSuchMethodException {
    ScriptEngineManager factory = new ScriptEngineManager();
    ScriptEngine engine = factory.getEngineByName("nashorn");
    engine.eval(parser);
    Invocable inv = (Invocable) engine;
    Object esprima = engine.get("esprima");
    Object tree = new Object();
    Object tokens = new Object();
    for (int i = 0; i < RUNS; ++i) {
      long start = System.nanoTime();
      tree = inv.invokeMethod(esprima, "parse", code);
      tokens = inv.invokeMethod(esprima, "tokenize", code);
      long stop = System.nanoTime();
      System.out.println("Run #" + (i + 1) + ": " + Math.round((stop - start) / 1e6) + " ms");
    }
    // System.out.println("Data is " + tokens.toString() + " and " + tree.toString());
  }

从代码可以看出,测试程序将执行Esprima的parse和tokenize来运行测试文件的内容,Rhino和Nashorn分别执行30次,在开始时候,Rhino需要1726 ms并且慢慢加速,最终稳定在950ms左右,Nashorn却有另一个特色,第一次运行耗时3682ms,但热身后很快加速,最终每次运行稳定在175ms,如下图所示

nashorn首先编译javascript代码为java字节码,然后运行在jvm上,底层也是使用invokedynamic命令来执行,所以运行速度很给力。

为何要用java实现javascript

这也是大部分同学关注的点,我认同的观点是:

1.成熟的GC

2.成熟的JIT编译器

3.多线程支持

4.丰富的标准库和第三方库

总得来说,充分利用了java平台的已有资源。

总结

新犀牛可以说是犀牛式战车,比Rhino速度快了许多,作为高性能的javascript运行环境,Nashorn有很多可能。

举例, Avatar.js 是依赖于Nashorn用以支持在JVM上实现Node.js编程模型,另外还增加了其他新的功能,如使用一个内建的负载平衡器实现多事件循环,以及使用多线程实现轻量消息传递机制;Avatar还提供了一个Model-Store, 基于JPA的纯粹的JavaScript ORM框架。

在企业中另外一种借力 Nashorn方式是脚本,相比通常我们使用Linux等shell脚本,现在我们也可以使用Javascript脚本和Java交互了,甚至使用Nashorn通过REST接口来监视服务器运行状况。

Java新特性之Nashorn的实例详解的更多相关文章

  1. java中List的用法和实例详解

    java中List的用法和实例详解 List的用法List包括List接口以及List接口的所有实现类.因为List接口实现了Collection接口,所以List接口拥有Collection接口提供 ...

  2. java8新特性(四)_Stream详解

    之前写过一篇用stream处理map的文章,但是对stream没有一个整体的认识,这次结合并发编程网和ibm中介绍stream的文章进行一个总结,我会着重写对list的处理,毕竟实际工作中大家每天进行 ...

  3. Java eclipse下 Ant build.xml实例详解

    在有eclipse集成环境下ant其实不是很重要,但有些项目需要用到,另外通过eclipse来学习和理解ant是个很好的途径,所以写他demo总结下要点,希望能够帮到大家. 一.本人测试环境eclip ...

  4. ASP.NET MVC5 新特性:Attribute路由使用详解 (转载)

    1.什么是Attribute路由?怎么样启用Attribute路由? 微软在 ASP.NET MVC5 中引入了一种新型路由:Attribute路由,顾名思义,Attribute路由是通过Attrib ...

  5. 转:Java eclipse下 Ant build.xml实例详解

    在有eclipse集成环境下ant其实不是很重要,但有些项目需要用到,另外通过eclipse来学习和理解ant是个很好的途径,所以写他demo总结下要点,希望能够帮到大家. 一.本人测试环境eclip ...

  6. Java操作FTP工具类(实例详解)

    这里使用Apache的FTP jar 包 没有使用Java自带的FTPjar包  工具类 package com.zit.ftp; import java.io.File; import java.i ...

  7. Java eclipse下 Ant build.xml实例详解 附完整项目源码

    在有eclipse集成环境下ant其实不是很重要,但有些项目需要用到,另外通过eclipse来学习和理解ant是个很好的途径,所以写他demo总结下要点,希望能够帮到大家. 一.本人测试环境eclip ...

  8. ASP.NET MVC5 新特性:Attribute路由使用详解

    1.什么是Attribute路由?怎么样启用Attribute路由? 微软在 ASP.NET MVC5 中引入了一种新型路由:Attribute路由,顾名思义,Attribute路由是通过Attrib ...

  9. Hi java新特性

    java新特性 1995.5.23 java语言 1996 jdk1.0 250个类在API 主要用在桌面型应用程序1997 jdk1.1 500 图形用户界面编程1998 jdk1.2 2300 J ...

随机推荐

  1. Postgresql 用户管理

    一, 设置超级用户密码 1  修改 pg_hba.conf 使超级用户postgres 可以登录到数据库中 host all all 127.0.0.1/32 trust 2 修改 postgres ...

  2. nginx停止

  3. Net特性类Description了解下

    NET特性类都有个特点类名+Attribute,继承基类Attribute,我们看下微软自带的特性类:DescriptionAttribute namespace System.ComponentMo ...

  4. PostgreSQL递归查询

    原料 --创建组织架构表 create table "Org"( "OrgId" ) primary key, "ParentId" ), ...

  5. unity 加载资源

    Unity3D中的资源的处理种类 Unity中的资源资源的处理种类大致分为:Resources.StreamingAssets.AssetBundle Resources 是作为一个Unity的保留文 ...

  6. 写了一个Windows服务,通过C#模拟网站用户登录并爬取BUG列表查询有没有新的BUG,并提醒我

    写了一个Windows服务,通过C#模拟网站用户登录并爬取BUG列表查询有没有新的BUG,并提醒我 1.HttpUtil工具类,用于模拟用户登录以及爬取网页: using System; using ...

  7. linux shell中"2>&1"含义

    在计划任务中经常可以看到.例如我们公司的计划任务举例: */ * * * * root cd /opt/xxxx/test_S1/html/xxxx/admin; php index.php task ...

  8. 微信小程序——扫码后提示“打开失败缺少ID”

    解决步骤: 进入通讯录tab->点击右上角添加朋友->搜索框输入:recover,拉到最底下选择小程序进行修复操作 参考:https://developers.weixin.qq.com/ ...

  9. 操作mysql的指令

    1,通过ip,端口,用户名,密码登陆数据 命令格式为:mysql -h ip -u root -p -P 3306例如:mysql -h 127.0.0.1 -u root -p -P 3306 2, ...

  10. 为IEnumerable类型添加Add方法

    IEnumerable类型原生是没有Add方法的,你可以用Contact方法去为它添加元素, 1 items = items.Concat(new[] { "foo" }); 也可 ...