Skip to content

Commit

Permalink
process: improve memoryUsage() performance
Browse files Browse the repository at this point in the history
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: #11497
Reviewed-By: Ben Noordhuis <[email protected]>
Reviewed-By: James M Snell <[email protected]>
Reviewed-By: Jeremiah Senkpiel <[email protected]>
Reviewed-By: Colin Ihrig <[email protected]>
  • Loading branch information
mscdex authored and jasnell committed Mar 9, 2017
1 parent c61d7d2 commit 0e636c8
Show file tree
Hide file tree
Showing 5 changed files with 46 additions and 21 deletions.
16 changes: 16 additions & 0 deletions benchmark/process/memoryUsage.js
Original file line number Diff line number Diff line change
@@ -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 change: 1 addition & 0 deletions lib/internal/bootstrap_node.js
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,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();
Expand Down
15 changes: 15 additions & 0 deletions lib/internal/process.js
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -100,6 +101,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
Expand Down
4 changes: 0 additions & 4 deletions src/env.h
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,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") \
Expand All @@ -115,8 +114,6 @@ namespace node {
V(flags_string, "flags") \
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") \
Expand Down Expand Up @@ -184,7 +181,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") \
Expand Down
31 changes: 14 additions & 17 deletions src/node.cc
Original file line number Diff line number Diff line change
Expand Up @@ -2290,25 +2290,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);
}


Expand Down

0 comments on commit 0e636c8

Please sign in to comment.