Browse Source

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>
v7.x
Brian White 8 years ago
committed by Italo A. Casas
parent
commit
54e1f0c219
No known key found for this signature in database GPG Key ID: 23EFEFE93C4CFFFE
  1. 16
      benchmark/process/memoryUsage.js
  2. 1
      lib/internal/bootstrap_node.js
  3. 15
      lib/internal/process.js
  4. 4
      src/env.h
  5. 31
      src/node.cc

16
benchmark/process/memoryUsage.js

@ -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

@ -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();

15
lib/internal/process.js

@ -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;
@ -98,6 +99,20 @@ 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

4
src/env.h

@ -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") \

31
src/node.cc

@ -2247,25 +2247,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);
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));
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);
isolate->GetHeapStatistics(&v8_heap_stats);
// 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());
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…
Cancel
Save