node: improve accessor perf of process.env
Set process.env array entries in JS. PR-URL: https://github.com/nodejs/node/pull/3780 Reviewed-By: Fedor Indutny <fedor@indutny.com>
This commit is contained in:
parent
36e8a2c63d
commit
56985ca258
18
benchmark/misc/bench-env.js
Normal file
18
benchmark/misc/bench-env.js
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
'use strict';
|
||||||
|
|
||||||
|
const common = require('../common');
|
||||||
|
|
||||||
|
const bench = common.createBenchmark(main, {
|
||||||
|
n: [1e5],
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
function main(conf) {
|
||||||
|
const n = conf.n >>> 0;
|
||||||
|
bench.start();
|
||||||
|
for (var i = 0; i < n; i++) {
|
||||||
|
// Access every item in object to process values.
|
||||||
|
Object.keys(process.env);
|
||||||
|
}
|
||||||
|
bench.end(n);
|
||||||
|
}
|
31
src/node.cc
31
src/node.cc
@ -2560,23 +2560,35 @@ static void EnvDeleter(Local<String> property,
|
|||||||
|
|
||||||
|
|
||||||
static void EnvEnumerator(const PropertyCallbackInfo<Array>& info) {
|
static void EnvEnumerator(const PropertyCallbackInfo<Array>& info) {
|
||||||
Isolate* isolate = info.GetIsolate();
|
Environment* env = Environment::GetCurrent(info);
|
||||||
|
Isolate* isolate = env->isolate();
|
||||||
|
Local<Context> ctx = env->context();
|
||||||
|
Local<Function> fn = env->push_values_to_array_function();
|
||||||
|
Local<Value> argv[NODE_PUSH_VAL_TO_ARRAY_MAX];
|
||||||
|
size_t idx = 0;
|
||||||
|
|
||||||
#ifdef __POSIX__
|
#ifdef __POSIX__
|
||||||
int size = 0;
|
int size = 0;
|
||||||
while (environ[size])
|
while (environ[size])
|
||||||
size++;
|
size++;
|
||||||
|
|
||||||
Local<Array> envarr = Array::New(isolate, size);
|
Local<Array> envarr = Array::New(isolate);
|
||||||
|
|
||||||
for (int i = 0; i < size; ++i) {
|
for (int i = 0; i < size; ++i) {
|
||||||
const char* var = environ[i];
|
const char* var = environ[i];
|
||||||
const char* s = strchr(var, '=');
|
const char* s = strchr(var, '=');
|
||||||
const int length = s ? s - var : strlen(var);
|
const int length = s ? s - var : strlen(var);
|
||||||
Local<String> name = String::NewFromUtf8(isolate,
|
argv[idx] = String::NewFromUtf8(isolate,
|
||||||
var,
|
var,
|
||||||
String::kNormalString,
|
String::kNormalString,
|
||||||
length);
|
length);
|
||||||
envarr->Set(i, name);
|
if (++idx >= ARRAY_SIZE(argv)) {
|
||||||
|
fn->Call(ctx, envarr, idx, argv).ToLocalChecked();
|
||||||
|
idx = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (idx > 0) {
|
||||||
|
fn->Call(ctx, envarr, idx, argv).ToLocalChecked();
|
||||||
}
|
}
|
||||||
#else // _WIN32
|
#else // _WIN32
|
||||||
WCHAR* environment = GetEnvironmentStringsW();
|
WCHAR* environment = GetEnvironmentStringsW();
|
||||||
@ -2584,7 +2596,6 @@ static void EnvEnumerator(const PropertyCallbackInfo<Array>& info) {
|
|||||||
return; // This should not happen.
|
return; // This should not happen.
|
||||||
Local<Array> envarr = Array::New(isolate);
|
Local<Array> envarr = Array::New(isolate);
|
||||||
WCHAR* p = environment;
|
WCHAR* p = environment;
|
||||||
int i = 0;
|
|
||||||
while (*p) {
|
while (*p) {
|
||||||
WCHAR *s;
|
WCHAR *s;
|
||||||
if (*p == L'=') {
|
if (*p == L'=') {
|
||||||
@ -2599,13 +2610,19 @@ static void EnvEnumerator(const PropertyCallbackInfo<Array>& info) {
|
|||||||
}
|
}
|
||||||
const uint16_t* two_byte_buffer = reinterpret_cast<const uint16_t*>(p);
|
const uint16_t* two_byte_buffer = reinterpret_cast<const uint16_t*>(p);
|
||||||
const size_t two_byte_buffer_len = s - p;
|
const size_t two_byte_buffer_len = s - p;
|
||||||
Local<String> value = String::NewFromTwoByte(isolate,
|
argv[idx] = String::NewFromTwoByte(isolate,
|
||||||
two_byte_buffer,
|
two_byte_buffer,
|
||||||
String::kNormalString,
|
String::kNormalString,
|
||||||
two_byte_buffer_len);
|
two_byte_buffer_len);
|
||||||
envarr->Set(i++, value);
|
if (++idx >= ARRAY_SIZE(argv)) {
|
||||||
|
fn->Call(ctx, envarr, idx, argv).ToLocalChecked();
|
||||||
|
idx = 0;
|
||||||
|
}
|
||||||
p = s + wcslen(s) + 1;
|
p = s + wcslen(s) + 1;
|
||||||
}
|
}
|
||||||
|
if (idx > 0) {
|
||||||
|
fn->Call(ctx, envarr, idx, argv).ToLocalChecked();
|
||||||
|
}
|
||||||
FreeEnvironmentStringsW(environment);
|
FreeEnvironmentStringsW(environment);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user