I use GWT JSNI to access native JavaScript libraries.
I wonder if it makes any difference in speed which data typ I pass through JSNI.
Example 1:
public static native int test(int value) /*-{
return this.computeSomething(value);
}-*/;
Example 2:
public static native double test(double value) /*-{
return this.computeSomething(value);
}-*/;
Assume that computeSomething() takes integer values as an argument and returns an integer value.
Do I have to cast the return value as proposed here: How to work with int values in gwt jsni methods
Does it make any difference in Performance when using int or double for JSNI Functions?
Is there a way to return an int from JSNI? There seems to be a bug here: https://code.google.com/p/google-web-toolkit/issues/detail?id=2693
When you call into JS from Java, the compiler trusts that the JSNI code follows the method signature exactly. This means that if a double
value is returned from an int
method, you might get other effects elsewhere. This yields the following results:
In terms of performance it makes no difference at all. Since GWT assumes that the JS will do what you say it will do, it doesn't do any extra work to verify that (except in dev mode, as a way to validate that the code makes sense)
There are several ways to cast from a JS Number which may be floating point to an integer, so that you can be certain that GWT/Java code can accept it. The first is to simply return a double
, and then in your Java code, cast to an int
, or use Math.round
to remove any unneeded precision. Another is to do in your JSNI what com.google.gwt.dom.client.Element#toInt32
does as of GWT 2.6:
/**
* Fast helper method to convert small doubles to 32-bit int.
*
* <p>Note: you should be aware that this uses JavaScript rounding and thus
* does NOT provide the same semantics as <code>int b = (int) someDouble;</code>.
* In particular, if x is outside the range [-2^31,2^31), then toInt32(x) would return a value
* equivalent to x modulo 2^32, whereas (int) x would evaluate to either MIN_INT or MAX_INT.
*/
private static native int toInt32(double val) /*-{
return val | 0;
}-*/;
Note the use of | 0
versus || 0
in your linked answer - the first is a bitwise OR, while the second is a boolean OR.
There is no problem returning int
from JSNI - the linked issue is about returning java.lang.Integer
, the boxed Java type around an int
. That issue is flawed, since there is no need for a JsArray<Integer>
since com.google.gwt.core.client.JsArrayNumber
exists already, you simply must cast to an int to deal with rounding issues.