Efficient way to convery v8::String to c string

2,435 views
Skip to first unread message

Ray Morgan

unread,
Dec 8, 2009, 2:26:54 AM12/8/09
to v8-users
Hey,

I am currently writing a Protocol Buffers library for Node.js.
Basically I am going to generate a thin v8 wrapper around the protobuf
generated C++ code. The main issue that I am coming up against is how
to convert a v8::String to a c string in an efficient way. Right now I
am doing:

String::AsciiValue data(args[0]->ToString());
ParseFromString(*data, data.length());

This works, but seems to be the main bottleneck that I am running up
against. Is there any more efficient way to go from v8::String ->
const char* or std::string?

Thanks.

Søren Gjesse

unread,
Dec 8, 2009, 3:04:52 AM12/8/09
to v8-u...@googlegroups.com
The construct you are using creates a copy of the V8::String into a char* bupper allocated for the String::AsciiValue object. This is the only way to get a V8::String sitting in the V8 heap as a C string. This is both due to GC issues and due to the internal representation of strings in V8 where a string object is not necessarily a sequential ASCII buffer.

However it might be possible for you to use external strings, but of cause that depends on the use-case. External strings are strings which have their actual string buffer outside the V8 heap, and when you have an external string it is possible get pointer to that string buffer without copying the string data. External strings can be created either when creating a string through the API using v8::String::NewExternal, or an external string can replace a normal string using v8::String::MakeExternal. If your strings are created from outside V8 in the first place consider v8::String::NewExternal, and if you are converting the same strings to c strings again and again consider v8::String::MakeExternal.

Regards,
Søren


Matthias Ernst

unread,
Dec 8, 2009, 5:12:50 AM12/8/09
to v8-u...@googlegroups.com
2009/12/8 Søren Gjesse <sgj...@chromium.org>:
> The construct you are using creates a copy of the V8::String into a char*
> bupper allocated for the String::AsciiValue object. This is the only way to
> get a V8::String sitting in the V8 heap as a C string. This is both due to
> GC issues and due to the internal representation of strings in V8 where a
> string object is not necessarily a sequential ASCII buffer.
> However it might be possible for you to use external strings, but of cause
> that depends on the use-case. External strings are strings which have their
> actual string buffer outside the V8 heap, and when you have an external
> string it is possible get pointer to that string buffer without copying the
> string data. External strings can be created either when creating a string
> through the API using v8::String::NewExternal, or an external string can
> replace a normal string using v8::String::MakeExternal. If your strings are
> created from outside V8 in the first place consider v8::String::NewExternal,
> and if you are converting the same strings to c strings again and again
> consider v8::String::MakeExternal.

I think there is a problem with encoding. Google Protocol Buffers
encode strings as UTF-8.
ExternalStringResource's must be either UCS2 or ASCII encoded.

Matthias

Søren Gjesse

unread,
Dec 8, 2009, 8:49:44 AM12/8/09
to v8-u...@googlegroups.com
Internally V8 uses either ASCII or UCS2 (two byte) to represent strings. As the character buffer of an external string is exposed directly to V8 the external string needs to be in one of these two encodings.

Regards,
Søren
Reply all
Reply to author
Forward
0 new messages