字节[]的GWT内部表示

时间:2014-07-13 08:41:52

标签: arrays gwt byte jsni

我正在开发一个GWT项目,我们偶尔会使用JSNI来调用本机JavaScript代码。性能瓶颈似乎是在Java代码和JavaScript代码之间来回传递值。具体来说,没有办法将Java []中的byte []传递给JS代码,反之亦然 - 只能传递int,byte,String等,而不能传递byte []。这意味着我们必须在调用之前将数组转换为字符串,然后转换回字节数组表示(byte []或UInt8Array)。这似乎是不必要的,因为GWT的byte []必须具有一些本机JavaScript表示。有谁知道GWT如何表示字节数组?可以选择更改GWT编译器以允许我们直接访问阵列。

1 个答案:

答案 0 :(得分:3)

几乎所有数字类型(包括byte)都表示为JavaScript编号(例外是盒装类型和long)。编译器根据需要插入范围检查或“溢出”以正确模拟预期的Java行为。

从GWT 2.6.x(和当前的GWT中继)开始,任何原始数字数组在编译时都实现为JavaScript数组。但是,在Dev模式下运行时,会使用本机Java数组,因此您无法编写简单地将Java数组传递给JavaScript的JSNI代码,并期望它能够正常运行。见http://www.gwtproject.org/doc/latest/DevGuideCodingBasicsJSNI.html#sharing

  

Java数组

     

opaque值,只能传递回Java代码

即使没有考虑开发模式,也要小心将Java数组视为JavaScript数组 - 任何未来的编译器优化都会发出类型数组(正如您在问题中提到的那样)可能会意外破坏您的代码。

也就是说,有很多方法可以在Gwt / Java代码中创建JavaScript数组 TypedArrays,以便可以在JavaScript中使用它们。使用JsArrayNumber类型来保存双重对象(回想一下JS' Numbers'实际上是Java double),或使用com.google.gwt.typedarrays.shared.Uint8Array类和其他的typedarrays包在Java中处理类型化数组。

就更改编译器而言,我在去年年底(https://gwt-review.googlesource.com/4260)提交了一个试图添加此功能的补丁。两个主要因素妨碍了这个想法的发挥:

  • 首先,在一个月左右的时间内,我的补丁发生了多次破坏的阵列编译。这些更改改进了通用对象数组,因此是有益的,我认为没有理由我的补丁最终无法工作。然而...
  • 补丁更改了所有原始数组(long除外,因为JS中没有64位int typedarray)基于ArrayBuffer。有点矛盾的是,在许多情况下,这引入了性能回归,因为现在任何小数组都必须被分配为类型化数组,并且当时在大多数/所有浏览器中这比实际创建典型JS数组要慢宾语。已经讨论了几个想法来解决这个问题 - 一个用于全局转换此功能的标志,一个注释来声明一个实例将是一个类型化数组,一个特殊的TypedJavaArrays工厂类来创建原始Java数组。由JS TypedArrays支持(所以任何性能问题都取决于用户)等等。

我仍然在时间允许的情况下追求这一点,并且无法确定它是否会制作GWT 2.7或更高版本 - 我们不想放慢所有GWT代码的速度一些特殊情况下,无论如何都可以引用typedarrays包。