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_cpuUsage();
|
||||
_process.setupMemoryUsage();
|
||||
_process.setupConfig(NativeModule._source);
|
||||
NativeModule.require('internal/process/warning').setup();
|
||||
NativeModule.require('internal/process/next_tick').setup();
|
||||
|
@ -11,6 +11,7 @@ function lazyConstants() {
|
||||
|
||||
exports.setup_cpuUsage = setup_cpuUsage;
|
||||
exports.setup_hrtime = setup_hrtime;
|
||||
exports.setupMemoryUsage = setupMemoryUsage;
|
||||
exports.setupConfig = setupConfig;
|
||||
exports.setupKillAndExit = setupKillAndExit;
|
||||
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) {
|
||||
// NativeModule._source
|
||||
// used for `process.config`, but not a real module
|
||||
|
@ -106,7 +106,6 @@ namespace node {
|
||||
V(exponent_string, "exponent") \
|
||||
V(exports_string, "exports") \
|
||||
V(ext_key_usage_string, "ext_key_usage") \
|
||||
V(external_string, "external") \
|
||||
V(external_stream_string, "_externalStream") \
|
||||
V(family_string, "family") \
|
||||
V(fatal_exception_string, "_fatalException") \
|
||||
@ -117,8 +116,6 @@ namespace node {
|
||||
V(get_string, "get") \
|
||||
V(gid_string, "gid") \
|
||||
V(handle_string, "handle") \
|
||||
V(heap_total_string, "heapTotal") \
|
||||
V(heap_used_string, "heapUsed") \
|
||||
V(homedir_string, "homedir") \
|
||||
V(hostmaster_string, "hostmaster") \
|
||||
V(ignore_string, "ignore") \
|
||||
@ -186,7 +183,6 @@ namespace node {
|
||||
V(rename_string, "rename") \
|
||||
V(replacement_string, "replacement") \
|
||||
V(retry_string, "retry") \
|
||||
V(rss_string, "rss") \
|
||||
V(serial_string, "serial") \
|
||||
V(scopeid_string, "scopeid") \
|
||||
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");
|
||||
}
|
||||
|
||||
Isolate* isolate = env->isolate();
|
||||
// V8 memory usage
|
||||
HeapStatistics v8_heap_stats;
|
||||
env->isolate()->GetHeapStatistics(&v8_heap_stats);
|
||||
isolate->GetHeapStatistics(&v8_heap_stats);
|
||||
|
||||
Local<Number> heap_total =
|
||||
Number::New(env->isolate(), v8_heap_stats.total_heap_size());
|
||||
Local<Number> heap_used =
|
||||
Number::New(env->isolate(), v8_heap_stats.used_heap_size());
|
||||
Local<Number> external_mem =
|
||||
Number::New(env->isolate(),
|
||||
env->isolate()->AdjustAmountOfExternalAllocatedMemory(0));
|
||||
// Get the double array pointer from the Float64Array argument.
|
||||
CHECK(args[0]->IsFloat64Array());
|
||||
Local<Float64Array> array = args[0].As<Float64Array>();
|
||||
CHECK_EQ(array->Length(), 4);
|
||||
Local<ArrayBuffer> ab = array->Buffer();
|
||||
double* fields = static_cast<double*>(ab->GetContents().Data());
|
||||
|
||||
Local<Object> info = Object::New(env->isolate());
|
||||
info->Set(env->rss_string(), Number::New(env->isolate(), rss));
|
||||
info->Set(env->heap_total_string(), heap_total);
|
||||
info->Set(env->heap_used_string(), heap_used);
|
||||
info->Set(env->external_string(), external_mem);
|
||||
|
||||
args.GetReturnValue().Set(info);
|
||||
fields[0] = rss;
|
||||
fields[1] = v8_heap_stats.total_heap_size();
|
||||
fields[2] = v8_heap_stats.used_heap_size();
|
||||
fields[3] = isolate->AdjustAmountOfExternalAllocatedMemory(0);
|
||||
}
|
||||
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user