Skip to content

Commit c6367e7

Browse files
committed
node: speed up ParseEncoding
Handle most popular cases in a trie-style, branching on a first character. Remove useless HandleScope which was only eating time without producing any value. PR-URL: #664 Reviewed-By: Ben Noordhuis <[email protected]>
1 parent 7604e6d commit c6367e7

File tree

2 files changed

+66
-26
lines changed

2 files changed

+66
-26
lines changed

src/node.cc

+63-23
Original file line numberDiff line numberDiff line change
@@ -1148,55 +1148,95 @@ Handle<Value> MakeCallback(Isolate* isolate,
11481148
}
11491149

11501150

1151-
enum encoding ParseEncoding(Isolate* isolate,
1152-
Handle<Value> encoding_v,
1153-
enum encoding _default) {
1154-
HandleScope scope(isolate);
1155-
1156-
if (!encoding_v->IsString())
1157-
return _default;
1158-
1159-
node::Utf8Value encoding(isolate, encoding_v);
1151+
enum encoding ParseEncoding(const char* encoding,
1152+
enum encoding default_encoding) {
1153+
switch (encoding[0]) {
1154+
case 'u':
1155+
// utf8, utf16le
1156+
if (encoding[1] == 't' && encoding[2] == 'f') {
1157+
// Skip `-`
1158+
encoding += encoding[3] == '-' ? 4 : 3;
1159+
if (encoding[0] == '8' && encoding[1] == '\0')
1160+
return UTF8;
1161+
if (strncmp(encoding, "16le", 4) == 0)
1162+
return UCS2;
1163+
1164+
// ucs2
1165+
} else if (encoding[1] == 'c' && encoding[2] == 's') {
1166+
encoding += encoding[3] == '-' ? 4 : 3;
1167+
if (encoding[0] == '2' && encoding[1] == '\0')
1168+
return UCS2;
1169+
}
1170+
break;
1171+
case 'b':
1172+
// binary
1173+
if (encoding[1] == 'i') {
1174+
if (strncmp(encoding + 2, "nary", 4) == 0)
1175+
return BINARY;
1176+
1177+
// buffer
1178+
} else if (encoding[1] == 'u') {
1179+
if (strncmp(encoding + 2, "ffer", 4) == 0)
1180+
return BUFFER;
1181+
}
1182+
break;
1183+
case '\0':
1184+
return default_encoding;
1185+
default:
1186+
break;
1187+
}
11601188

1161-
if (strcasecmp(*encoding, "utf8") == 0) {
1189+
if (strcasecmp(encoding, "utf8") == 0) {
11621190
return UTF8;
1163-
} else if (strcasecmp(*encoding, "utf-8") == 0) {
1191+
} else if (strcasecmp(encoding, "utf-8") == 0) {
11641192
return UTF8;
1165-
} else if (strcasecmp(*encoding, "ascii") == 0) {
1193+
} else if (strcasecmp(encoding, "ascii") == 0) {
11661194
return ASCII;
1167-
} else if (strcasecmp(*encoding, "base64") == 0) {
1195+
} else if (strcasecmp(encoding, "base64") == 0) {
11681196
return BASE64;
1169-
} else if (strcasecmp(*encoding, "ucs2") == 0) {
1197+
} else if (strcasecmp(encoding, "ucs2") == 0) {
11701198
return UCS2;
1171-
} else if (strcasecmp(*encoding, "ucs-2") == 0) {
1199+
} else if (strcasecmp(encoding, "ucs-2") == 0) {
11721200
return UCS2;
1173-
} else if (strcasecmp(*encoding, "utf16le") == 0) {
1201+
} else if (strcasecmp(encoding, "utf16le") == 0) {
11741202
return UCS2;
1175-
} else if (strcasecmp(*encoding, "utf-16le") == 0) {
1203+
} else if (strcasecmp(encoding, "utf-16le") == 0) {
11761204
return UCS2;
1177-
} else if (strcasecmp(*encoding, "binary") == 0) {
1205+
} else if (strcasecmp(encoding, "binary") == 0) {
11781206
return BINARY;
1179-
} else if (strcasecmp(*encoding, "buffer") == 0) {
1207+
} else if (strcasecmp(encoding, "buffer") == 0) {
11801208
return BUFFER;
1181-
} else if (strcasecmp(*encoding, "hex") == 0) {
1209+
} else if (strcasecmp(encoding, "hex") == 0) {
11821210
return HEX;
1183-
} else if (strcasecmp(*encoding, "raw") == 0) {
1211+
} else if (strcasecmp(encoding, "raw") == 0) {
11841212
if (!no_deprecation) {
11851213
fprintf(stderr, "'raw' (array of integers) has been removed. "
11861214
"Use 'binary'.\n");
11871215
}
11881216
return BINARY;
1189-
} else if (strcasecmp(*encoding, "raws") == 0) {
1217+
} else if (strcasecmp(encoding, "raws") == 0) {
11901218
if (!no_deprecation) {
11911219
fprintf(stderr, "'raws' encoding has been renamed to 'binary'. "
11921220
"Please update your code.\n");
11931221
}
11941222
return BINARY;
11951223
} else {
1196-
return _default;
1224+
return default_encoding;
11971225
}
11981226
}
11991227

1228+
1229+
enum encoding ParseEncoding(Isolate* isolate,
1230+
Handle<Value> encoding_v,
1231+
enum encoding default_encoding) {
1232+
if (!encoding_v->IsString())
1233+
return default_encoding;
1234+
1235+
node::Utf8Value encoding(isolate, encoding_v);
1236+
1237+
return ParseEncoding(*encoding, default_encoding);
1238+
}
1239+
12001240
Local<Value> Encode(Isolate* isolate,
12011241
const char* buf,
12021242
size_t len,

src/node.h

+3-3
Original file line numberDiff line numberDiff line change
@@ -231,12 +231,12 @@ inline void NODE_SET_PROTOTYPE_METHOD(v8::Handle<v8::FunctionTemplate> recv,
231231
enum encoding {ASCII, UTF8, BASE64, UCS2, BINARY, HEX, BUFFER};
232232
enum encoding ParseEncoding(v8::Isolate* isolate,
233233
v8::Handle<v8::Value> encoding_v,
234-
enum encoding _default = BINARY);
234+
enum encoding default_encoding = BINARY);
235235
NODE_DEPRECATED("Use ParseEncoding(isolate, ...)",
236236
inline enum encoding ParseEncoding(
237237
v8::Handle<v8::Value> encoding_v,
238-
enum encoding _default = BINARY) {
239-
return ParseEncoding(v8::Isolate::GetCurrent(), encoding_v, _default);
238+
enum encoding default_encoding = BINARY) {
239+
return ParseEncoding(v8::Isolate::GetCurrent(), encoding_v, default_encoding);
240240
})
241241

242242
NODE_EXTERN void FatalException(v8::Isolate* isolate,

0 commit comments

Comments
 (0)