Skip to content

Commit 733532e

Browse files
radexfacebook-github-bot
authored andcommitted
Make JSStringToSTLString 23x faster (#26955)
Summary: In my app I have a case where I need to pass a very large string (45MB) between JS and native. This is obviously suboptimal, but… this is where I'm at. The main bottleneck to doing this turned out to be `jsi`'s `JSStringToSTLString()`, which was extremely slow. In my case, 4.7s to execute. After this change, 204ms. I don't really know C++, so I'm not sure this code is 100% correct and safe, and I bet it could be done even better by avoiding the extra memory allocation (would shave off another 70ms). ## Changelog [General] [Changed] - Make JSStringToSTLString 23x faster Pull Request resolved: #26955 Reviewed By: shergin Differential Revision: D19578728 Pulled By: motiz88 fbshipit-source-id: 2fbce83166953ce928f0a6aa36eed710bfe05383
1 parent 142c66f commit 733532e

File tree

1 file changed

+15
-3
lines changed

1 file changed

+15
-3
lines changed

ReactCommon/jsi/JSCRuntime.cpp

+15-3
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99

1010
#include <JavaScriptCore/JavaScript.h>
1111
#include <atomic>
12+
#include <array>
1213
#include <condition_variable>
1314
#include <cstdlib>
1415
#include <jsi/jsilib.h>
@@ -285,10 +286,21 @@ class JSCRuntime : public jsi::Runtime {
285286
// JSStringRef utilities
286287
namespace {
287288
std::string JSStringToSTLString(JSStringRef str) {
289+
// Small string optimization: Avoid one heap allocation for strings that fit
290+
// in stackBuffer.size() bytes of UTF-8 (including the null terminator).
291+
std::array<char, 20> stackBuffer;
292+
std::unique_ptr<char[]> heapBuffer;
293+
char *buffer;
288294
size_t maxBytes = JSStringGetMaximumUTF8CStringSize(str);
289-
std::vector<char> buffer(maxBytes);
290-
JSStringGetUTF8CString(str, buffer.data(), maxBytes);
291-
return std::string(buffer.data());
295+
if (maxBytes <= stackBuffer.size()) {
296+
buffer = stackBuffer.data();
297+
} else {
298+
heapBuffer = std::make_unique<char[]>(maxBytes);
299+
buffer = heapBuffer.get();
300+
}
301+
size_t actualBytes = JSStringGetUTF8CString(str, buffer, maxBytes);
302+
// NOTE: By definition, maxBytes >= actualBytes >= 1.
303+
return std::string(buffer, actualBytes - 1);
292304
}
293305

294306
JSStringRef getLengthString() {

0 commit comments

Comments
 (0)