process: improve memoryUsage() performance
Creating an object in JS and using a typed array to transfer values from C++ to JS is faster than creating an object and setting properties in C++. The included benchmark shows ~34% increase in performance with this change. PR-URL: https://github.com/nodejs/node/pull/11497 Reviewed-By: Ben Noordhuis <info@bnoordhuis.nl> Reviewed-By: James M Snell <jasnell@gmail.com> Reviewed-By: Jeremiah Senkpiel <fishrock123@rocketmail.com> Reviewed-By: Colin Ihrig <cjihrig@gmail.com>
This commit is contained in:
parent
dd2e135560
commit
f385f77f1d
16
benchmark/process/memoryUsage.js
Normal file
16
benchmark/process/memoryUsage.js
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
'use strict';
|
||||||
|
|
||||||
|
var common = require('../common.js');
|
||||||
|
var bench = common.createBenchmark(main, {
|
||||||
|
n: [1e5]
|
||||||
|
});
|
||||||
|
|
||||||
|
function main(conf) {
|
||||||
|
var n = +conf.n;
|
||||||
|
|
||||||
|
bench.start();
|
||||||
|
for (var i = 0; i < n; i++) {
|
||||||
|
process.memoryUsage();
|
||||||
|
}
|
||||||
|
bench.end(n);
|
||||||
|
}
|
1
lib/internal/bootstrap_node.js
vendored
1
lib/internal/bootstrap_node.js
vendored
@ -38,6 +38,7 @@
|
|||||||
|
|
||||||
_process.setup_hrtime();
|
_process.setup_hrtime();
|
||||||
_process.setup_cpuUsage();
|
_process.setup_cpuUsage();
|
||||||
|
_process.setupMemoryUsage();
|
||||||
_process.setupConfig(NativeModule._source);
|
_process.setupConfig(NativeModule._source);
|
||||||
NativeModule.require('internal/process/warning').setup();
|
NativeModule.require('internal/process/warning').setup();
|
||||||
NativeModule.require('internal/process/next_tick').setup();
|
NativeModule.require('internal/process/next_tick').setup();
|
||||||
|
@ -11,6 +11,7 @@ function lazyConstants() {
|
|||||||
|
|
||||||
exports.setup_cpuUsage = setup_cpuUsage;
|
exports.setup_cpuUsage = setup_cpuUsage;
|
||||||
exports.setup_hrtime = setup_hrtime;
|
exports.setup_hrtime = setup_hrtime;
|
||||||
|
exports.setupMemoryUsage = setupMemoryUsage;
|
||||||
exports.setupConfig = setupConfig;
|
exports.setupConfig = setupConfig;
|
||||||
exports.setupKillAndExit = setupKillAndExit;
|
exports.setupKillAndExit = setupKillAndExit;
|
||||||
exports.setupSignalHandlers = setupSignalHandlers;
|
exports.setupSignalHandlers = setupSignalHandlers;
|
||||||
@ -101,6 +102,21 @@ function setup_hrtime() {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function setupMemoryUsage() {
|
||||||
|
const memoryUsage_ = process.memoryUsage;
|
||||||
|
const memValues = new Float64Array(4);
|
||||||
|
|
||||||
|
process.memoryUsage = function memoryUsage() {
|
||||||
|
memoryUsage_(memValues);
|
||||||
|
return {
|
||||||
|
rss: memValues[0],
|
||||||
|
heapTotal: memValues[1],
|
||||||
|
heapUsed: memValues[2],
|
||||||
|
external: memValues[3]
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
function setupConfig(_source) {
|
function setupConfig(_source) {
|
||||||
// NativeModule._source
|
// NativeModule._source
|
||||||
// used for `process.config`, but not a real module
|
// used for `process.config`, but not a real module
|
||||||
|
@ -106,7 +106,6 @@ namespace node {
|
|||||||
V(exponent_string, "exponent") \
|
V(exponent_string, "exponent") \
|
||||||
V(exports_string, "exports") \
|
V(exports_string, "exports") \
|
||||||
V(ext_key_usage_string, "ext_key_usage") \
|
V(ext_key_usage_string, "ext_key_usage") \
|
||||||
V(external_string, "external") \
|
|
||||||
V(external_stream_string, "_externalStream") \
|
V(external_stream_string, "_externalStream") \
|
||||||
V(family_string, "family") \
|
V(family_string, "family") \
|
||||||
V(fatal_exception_string, "_fatalException") \
|
V(fatal_exception_string, "_fatalException") \
|
||||||
@ -117,8 +116,6 @@ namespace node {
|
|||||||
V(get_string, "get") \
|
V(get_string, "get") \
|
||||||
V(gid_string, "gid") \
|
V(gid_string, "gid") \
|
||||||
V(handle_string, "handle") \
|
V(handle_string, "handle") \
|
||||||
V(heap_total_string, "heapTotal") \
|
|
||||||
V(heap_used_string, "heapUsed") \
|
|
||||||
V(homedir_string, "homedir") \
|
V(homedir_string, "homedir") \
|
||||||
V(hostmaster_string, "hostmaster") \
|
V(hostmaster_string, "hostmaster") \
|
||||||
V(ignore_string, "ignore") \
|
V(ignore_string, "ignore") \
|
||||||
@ -186,7 +183,6 @@ namespace node {
|
|||||||
V(rename_string, "rename") \
|
V(rename_string, "rename") \
|
||||||
V(replacement_string, "replacement") \
|
V(replacement_string, "replacement") \
|
||||||
V(retry_string, "retry") \
|
V(retry_string, "retry") \
|
||||||
V(rss_string, "rss") \
|
|
||||||
V(serial_string, "serial") \
|
V(serial_string, "serial") \
|
||||||
V(scopeid_string, "scopeid") \
|
V(scopeid_string, "scopeid") \
|
||||||
V(sent_shutdown_string, "sentShutdown") \
|
V(sent_shutdown_string, "sentShutdown") \
|
||||||
|
27
src/node.cc
27
src/node.cc
@ -2270,25 +2270,22 @@ void MemoryUsage(const FunctionCallbackInfo<Value>& args) {
|
|||||||
return env->ThrowUVException(err, "uv_resident_set_memory");
|
return env->ThrowUVException(err, "uv_resident_set_memory");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Isolate* isolate = env->isolate();
|
||||||
// V8 memory usage
|
// V8 memory usage
|
||||||
HeapStatistics v8_heap_stats;
|
HeapStatistics v8_heap_stats;
|
||||||
env->isolate()->GetHeapStatistics(&v8_heap_stats);
|
isolate->GetHeapStatistics(&v8_heap_stats);
|
||||||
|
|
||||||
Local<Number> heap_total =
|
// Get the double array pointer from the Float64Array argument.
|
||||||
Number::New(env->isolate(), v8_heap_stats.total_heap_size());
|
CHECK(args[0]->IsFloat64Array());
|
||||||
Local<Number> heap_used =
|
Local<Float64Array> array = args[0].As<Float64Array>();
|
||||||
Number::New(env->isolate(), v8_heap_stats.used_heap_size());
|
CHECK_EQ(array->Length(), 4);
|
||||||
Local<Number> external_mem =
|
Local<ArrayBuffer> ab = array->Buffer();
|
||||||
Number::New(env->isolate(),
|
double* fields = static_cast<double*>(ab->GetContents().Data());
|
||||||
env->isolate()->AdjustAmountOfExternalAllocatedMemory(0));
|
|
||||||
|
|
||||||
Local<Object> info = Object::New(env->isolate());
|
fields[0] = rss;
|
||||||
info->Set(env->rss_string(), Number::New(env->isolate(), rss));
|
fields[1] = v8_heap_stats.total_heap_size();
|
||||||
info->Set(env->heap_total_string(), heap_total);
|
fields[2] = v8_heap_stats.used_heap_size();
|
||||||
info->Set(env->heap_used_string(), heap_used);
|
fields[3] = isolate->AdjustAmountOfExternalAllocatedMemory(0);
|
||||||
info->Set(env->external_string(), external_mem);
|
|
||||||
|
|
||||||
args.GetReturnValue().Set(info);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user