Skip to content

Commit

Permalink
Try out Flatten API
Browse files Browse the repository at this point in the history
Speeds up WriteUtf8 significantly when dealing with strings made by the
concatenation of many others.
  • Loading branch information
ry committed Apr 6, 2010
1 parent ca0038b commit 38041fc
Show file tree
Hide file tree
Showing 5 changed files with 42 additions and 0 deletions.
7 changes: 7 additions & 0 deletions deps/v8/include/v8.h
Original file line number Diff line number Diff line change
Expand Up @@ -865,6 +865,13 @@ class V8EXPORT String : public Primitive {
int length = -1,
int* nchars = NULL) const; // UTF-8

/**
* Flatten internal memory. Operations on the string tend to run faster
* after flattening especially if the string is a concatenation of many
* others.
*/
void Flatten();

/**
* A zero length string.
*/
Expand Down
7 changes: 7 additions & 0 deletions deps/v8/src/api.cc
Original file line number Diff line number Diff line change
Expand Up @@ -2731,6 +2731,13 @@ int String::Write(uint16_t* buffer, int start, int length) const {
}


void v8::String::Flatten() {
EnsureInitialized("v8::String::Flatten()");
i::Handle<i::String> str = Utils::OpenHandle(this);
i::FlattenString(str);
}


bool v8::String::IsExternal() const {
EnsureInitialized("v8::String::IsExternal()");
i::Handle<i::String> str = Utils::OpenHandle(this);
Expand Down
25 changes: 25 additions & 0 deletions deps/v8/test/cctest/test-strings.cc
Original file line number Diff line number Diff line change
Expand Up @@ -347,6 +347,31 @@ TEST(Utf8Conversion) {
}


TEST(StringConcatFlatten) {
InitializeVM();
v8::HandleScope handle_scope;

const char* stringA = "abc";
const char* stringB = "def";

v8::Local<v8::String> a = v8::String::New(stringA);
v8::Local<v8::String> b = v8::String::New(stringB);

v8::Local<v8::String> cons = v8::String::Concat(a,b);
cons->Flatten();

char buffer[7];
cons->WriteUtf8(buffer);

int i;
for (i = 0; i < 3; i++)
CHECK_EQ(stringA[i], buffer[i]);

for (i = 0; i < 3; i++)
CHECK_EQ(stringB[i], buffer[i+3]);
}


TEST(ExternalShortStringAdd) {
ZoneScope zone(DELETE_ON_EXIT);

Expand Down
1 change: 1 addition & 0 deletions src/node.cc
Original file line number Diff line number Diff line change
Expand Up @@ -327,6 +327,7 @@ ssize_t DecodeWrite(char *buf,

uint16_t * twobytebuf = new uint16_t[buflen];

str->Flatten();
str->Write(twobytebuf, 0, buflen);

for (size_t i = 0; i < buflen; i++) {
Expand Down
2 changes: 2 additions & 0 deletions src/node_buffer.cc
Original file line number Diff line number Diff line change
Expand Up @@ -308,6 +308,7 @@ Handle<Value> Buffer::Utf8Write(const Arguments &args) {

const char *p = buffer->data() + offset;

s->Flatten();
int written = s->WriteUtf8((char*)p, buffer->length_ - offset);

if (written > 0 && p[written-1] == '\0') written--;
Expand Down Expand Up @@ -340,6 +341,7 @@ Handle<Value> Buffer::AsciiWrite(const Arguments &args) {

size_t towrite = MIN((unsigned long) s->Length(), buffer->length_ - offset);

s->Flatten();
int written = s->WriteAscii((char*)p, 0, towrite);
return scope.Close(Integer::New(written));
}
Expand Down

0 comments on commit 38041fc

Please sign in to comment.