Search code examples
javaandroidperformancejava-native-interfacev8

What is the fastest way to convert v8::String to jstring in JNI?


I would like to avoid string transformation during conversion. Because it is slow. I suggest that internally V8 String and Java jstring are the same sequence of wide char, so maybe it's possible to copy without de/encoding, or maybe even avoid copying completely?

v8::String::Value v8_text(args[1]); // get the v8 string from arguments
wchar_t* w_chars = (wchar_t*)(*v8_text);
jstring j_text = (Env)->NewString((jchar*)w_chars, v8_text.length());

is the above already the most efficient way?

than you


Solution

  • You are right, given some assumptions.

    A Java string is a counted sequence of code units of the UTF-16 encoding of Unicode characters. The endianness is meant to match the default for the OS.

    A JavaScript string is a counted sequence of 16-bit unsigned integers.

    V8 does not transform the data for strings unless you invoke the functions that do so (i.e., to ASCII or UTF-8).

    So, if your input is in fact a Unicode character string with a UTF-16 encoding with the expected endianness then the code you give will work and should be the most efficient.

    However,

    wchar_t* w_chars = (wchar_t*)(*v8_text);
    

    is a bit misleading since wchar_t has an implementation-dependent size. Ultimately, you just want to cast the pointer to jchar * so, if this step is necessary, I suggest char16_t * or uint16_t * instead since they express the assumption that the data is structured in 2 byte chunks with an endianness.