diff options
author | Bert Belder <bertbelder@gmail.com> | 2015-01-13 02:32:09 +0100 |
---|---|---|
committer | Bert Belder <bertbelder@gmail.com> | 2015-01-13 02:35:27 +0100 |
commit | 0bf1d124af481ac9be095fcb846a1aad08595233 (patch) | |
tree | a86f47d152523eda52a2e7ecb9fb564410386190 /src | |
parent | f468e5f1ec34d51f1691ab1f8c9cd813ebee85ef (diff) | |
download | node-new-0bf1d124af481ac9be095fcb846a1aad08595233.tar.gz |
http: optimize on_headers_complete
Use an array instead of an object to pass a parsed header chunk from c++
to javascript. This offers a 5-10% speedup on the http_simple benchmark,
as evidenced by running:
ab -k -t 100 -c 100 http://127.0.0.1:8000/bytes/100
PR: https://github.com/iojs/io.js/pull/292
Reviewed-by: Ben Noordhuis <info@bnoordhuis.nl>
Diffstat (limited to 'src')
-rw-r--r-- | src/env.h | 9 | ||||
-rw-r--r-- | src/node_http_parser.cc | 59 |
2 files changed, 37 insertions, 31 deletions
@@ -92,7 +92,6 @@ namespace node { V(fsevent_string, "FSEvent") \ V(gid_string, "gid") \ V(handle_string, "handle") \ - V(headers_string, "headers") \ V(heap_size_limit_string, "heap_size_limit") \ V(heap_total_string, "heapTotal") \ V(heap_used_string, "heapUsed") \ @@ -114,7 +113,6 @@ namespace node { V(mark_sweep_compact_string, "mark-sweep-compact") \ V(max_buffer_string, "maxBuffer") \ V(message_string, "message") \ - V(method_string, "method") \ V(minttl_string, "minttl") \ V(mode_string, "mode") \ V(model_string, "model") \ @@ -176,7 +174,6 @@ namespace node { V(service_string, "service") \ V(servername_string, "servername") \ V(session_id_string, "sessionId") \ - V(should_keep_alive_string, "shouldKeepAlive") \ V(signal_string, "signal") \ V(size_string, "size") \ V(smalloc_p_string, "_smalloc_p") \ @@ -184,8 +181,6 @@ namespace node { V(sni_context_string, "sni_context") \ V(speed_string, "speed") \ V(stack_string, "stack") \ - V(status_code_string, "statusCode") \ - V(status_message_string, "statusMessage") \ V(status_string, "status") \ V(stdio_string, "stdio") \ V(subject_string, "subject") \ @@ -209,16 +204,12 @@ namespace node { V(type_string, "type") \ V(uid_string, "uid") \ V(unknown_string, "<unknown>") \ - V(upgrade_string, "upgrade") \ - V(url_string, "url") \ V(used_heap_size_string, "used_heap_size") \ V(user_string, "user") \ V(uv_string, "uv") \ V(valid_from_string, "valid_from") \ V(valid_to_string, "valid_to") \ V(verify_error_string, "verifyError") \ - V(version_major_string, "versionMajor") \ - V(version_minor_string, "versionMinor") \ V(version_string, "version") \ V(weight_string, "weight") \ V(windows_verbatim_arguments_string, "windowsVerbatimArguments") \ diff --git a/src/node_http_parser.cc b/src/node_http_parser.cc index 284e786917..f71302d313 100644 --- a/src/node_http_parser.cc +++ b/src/node_http_parser.cc @@ -34,6 +34,7 @@ namespace node { using v8::Array; +using v8::Boolean; using v8::Context; using v8::Exception; using v8::Function; @@ -46,6 +47,7 @@ using v8::Local; using v8::Object; using v8::String; using v8::Uint32; +using v8::Undefined; using v8::Value; const uint32_t kOnHeaders = 0; @@ -218,55 +220,68 @@ class Parser : public BaseObject { HTTP_CB(on_headers_complete) { + // Arguments for the on-headers-complete javascript callback. This + // list needs to be kept in sync with the actual argument list for + // `parserOnHeadersComplete` in lib/_http_common.js. + enum on_headers_complete_arg_index { + A_VERSION_MAJOR = 0, + A_VERSION_MINOR, + A_HEADERS, + A_METHOD, + A_URL, + A_STATUS_CODE, + A_STATUS_MESSAGE, + A_UPGRADE, + A_SHOULD_KEEP_ALIVE, + A_MAX + }; + + Local<Value> argv[A_MAX]; Local<Object> obj = object(); Local<Value> cb = obj->Get(kOnHeadersComplete); if (!cb->IsFunction()) return 0; - Local<Object> message_info = Object::New(env()->isolate()); + Local<Value> undefined = Undefined(env()->isolate()); + for (size_t i = 0; i < ARRAY_SIZE(argv); i++) + argv[i] = undefined; if (have_flushed_) { // Slow case, flush remaining headers. Flush(); } else { // Fast case, pass headers and URL to JS land. - message_info->Set(env()->headers_string(), CreateHeaders()); + argv[A_HEADERS] = CreateHeaders(); if (parser_.type == HTTP_REQUEST) - message_info->Set(env()->url_string(), url_.ToString(env())); + argv[A_URL] = url_.ToString(env()); } - num_fields_ = num_values_ = 0; + + num_fields_ = 0; + num_values_ = 0; // METHOD if (parser_.type == HTTP_REQUEST) { - message_info->Set(env()->method_string(), - Uint32::NewFromUnsigned(env()->isolate(), - parser_.method)); + argv[A_METHOD] = + Uint32::NewFromUnsigned(env()->isolate(), parser_.method); } // STATUS if (parser_.type == HTTP_RESPONSE) { - message_info->Set(env()->status_code_string(), - Integer::New(env()->isolate(), parser_.status_code)); - message_info->Set(env()->status_message_string(), - status_message_.ToString(env())); + argv[A_STATUS_CODE] = + Integer::New(env()->isolate(), parser_.status_code); + argv[A_STATUS_MESSAGE] = status_message_.ToString(env()); } // VERSION - message_info->Set(env()->version_major_string(), - Integer::New(env()->isolate(), parser_.http_major)); - message_info->Set(env()->version_minor_string(), - Integer::New(env()->isolate(), parser_.http_minor)); + argv[A_VERSION_MAJOR] = Integer::New(env()->isolate(), parser_.http_major); + argv[A_VERSION_MINOR] = Integer::New(env()->isolate(), parser_.http_minor); - message_info->Set(env()->should_keep_alive_string(), - http_should_keep_alive(&parser_) ? - True(env()->isolate()) : False(env()->isolate())); + argv[A_SHOULD_KEEP_ALIVE] = + Boolean::New(env()->isolate(), http_should_keep_alive(&parser_)); - message_info->Set(env()->upgrade_string(), - parser_.upgrade ? True(env()->isolate()) - : False(env()->isolate())); + argv[A_UPGRADE] = Boolean::New(env()->isolate(), parser_.upgrade); - Local<Value> argv[1] = { message_info }; Local<Value> head_response = cb.As<Function>()->Call(obj, ARRAY_SIZE(argv), argv); |