arrays - byte[] 的 GWT 内部表示

标签 arrays gwt byte jsni

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

最佳答案

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

从 GWT 2.6.x(和当前的 GWT 主干)开始,任何原始数字数组在编译时都被实现为 JavaScript 数组。但是,在开发模式下运行时,将使用 native Java 数组,因此您无法编写仅将 Java 数组传递给 JavaScript 的 JSNI 代码,并期望其正常运行。请参阅http://www.gwtproject.org/doc/latest/DevGuideCodingBasicsJSNI.html#sharing :

Java array

opaque value that can only be passed back into Java code

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

也就是说,有多种方法可以在 Gwt/Java 代码中创建 JavaScript 数组 TypedArray,以便您可以从 JavaScript 使用它们。使用 JsArrayNumber 类型来保存 double 对象(回想一下,JS“数字”实际上是 Java double),或者使用 com.google.gwt.typedarrays.shared .Uint8Array 类和 typedarrays 包的其余部分用于处理 Java 中的类型化数组。

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

  • 首先,也是最重要的,数组编译发生了其他变化,在一个月左右的时间里多次破坏了我的补丁。这些更改改进了一般对象数组,因此是有益的,而且我认为我的补丁最终没有理由不能工作。然而...
  • 该补丁将所有原始数组(除了long,因为JS中没有64位int类型数组)更改为基于ArrayBuffer。有点矛盾的是,这在许多情况下都会导致性能下降,因为现在任何小数组都必须分配为类型化数组,并且当时在大多数/所有浏览器中这比实际创建典型的 JS 数组要慢目的。已经讨论了几种处理这个问题的想法 - 全局打开/关闭此功能的标志、声明实例将是类型化数组的注释、用于创建原始 Java 的特殊 TypedJavaArrays 工厂类由 JS TypedArrays 支持的数组(因此任何性能问题都取决于用户)等。

如果时间允许,我仍在追求这一目标,并且不能确定它是否会成为 GWT 2.7 或更高版本 - 我们不想因为某些特殊情况而减慢所有 GWT 代码的速度无论如何都可以引用 typedarrays 包。

关于arrays - byte[] 的 GWT 内部表示,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24720940/

相关文章:

python - 使用像 numpy 数组这样的函数

java - 如何随机化一个数组以便一次打印 x% 的值?

GWT 历史记录删除项目

GWT 通过属性获取元素

c - 4字节(32位)的IEEE 754算术

javascript - 如何找出 `size`,其中 `girth` 等于 3.5

javascript - 在vuejs中访问数组内部数组的值

java - GWT 自定义事件处理程序

java - 为什么根据移位顺序对移位字节进行移位会产生不同的值?

sql - 为什么数据库模式通常包含 32、64、128 等