Skip to content

Commit f385f77

Browse files
mscdexjasnell
authored andcommitted
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: #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]>
1 parent dd2e135 commit f385f77

File tree

5 files changed

+47
-21
lines changed

5 files changed

+47
-21
lines changed

benchmark/process/memoryUsage.js

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
'use strict';
2+
3+
var common = require('../common.js');
4+
var bench = common.createBenchmark(main, {
5+
n: [1e5]
6+
});
7+
8+
function main(conf) {
9+
var n = +conf.n;
10+
11+
bench.start();
12+
for (var i = 0; i < n; i++) {
13+
process.memoryUsage();
14+
}
15+
bench.end(n);
16+
}

lib/internal/bootstrap_node.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@
3838

3939
_process.setup_hrtime();
4040
_process.setup_cpuUsage();
41+
_process.setupMemoryUsage();
4142
_process.setupConfig(NativeModule._source);
4243
NativeModule.require('internal/process/warning').setup();
4344
NativeModule.require('internal/process/next_tick').setup();

lib/internal/process.js

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ function lazyConstants() {
1111

1212
exports.setup_cpuUsage = setup_cpuUsage;
1313
exports.setup_hrtime = setup_hrtime;
14+
exports.setupMemoryUsage = setupMemoryUsage;
1415
exports.setupConfig = setupConfig;
1516
exports.setupKillAndExit = setupKillAndExit;
1617
exports.setupSignalHandlers = setupSignalHandlers;
@@ -101,6 +102,21 @@ function setup_hrtime() {
101102
};
102103
}
103104

105+
function setupMemoryUsage() {
106+
const memoryUsage_ = process.memoryUsage;
107+
const memValues = new Float64Array(4);
108+
109+
process.memoryUsage = function memoryUsage() {
110+
memoryUsage_(memValues);
111+
return {
112+
rss: memValues[0],
113+
heapTotal: memValues[1],
114+
heapUsed: memValues[2],
115+
external: memValues[3]
116+
};
117+
};
118+
}
119+
104120
function setupConfig(_source) {
105121
// NativeModule._source
106122
// used for `process.config`, but not a real module

src/env.h

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -106,7 +106,6 @@ namespace node {
106106
V(exponent_string, "exponent") \
107107
V(exports_string, "exports") \
108108
V(ext_key_usage_string, "ext_key_usage") \
109-
V(external_string, "external") \
110109
V(external_stream_string, "_externalStream") \
111110
V(family_string, "family") \
112111
V(fatal_exception_string, "_fatalException") \
@@ -117,8 +116,6 @@ namespace node {
117116
V(get_string, "get") \
118117
V(gid_string, "gid") \
119118
V(handle_string, "handle") \
120-
V(heap_total_string, "heapTotal") \
121-
V(heap_used_string, "heapUsed") \
122119
V(homedir_string, "homedir") \
123120
V(hostmaster_string, "hostmaster") \
124121
V(ignore_string, "ignore") \
@@ -186,7 +183,6 @@ namespace node {
186183
V(rename_string, "rename") \
187184
V(replacement_string, "replacement") \
188185
V(retry_string, "retry") \
189-
V(rss_string, "rss") \
190186
V(serial_string, "serial") \
191187
V(scopeid_string, "scopeid") \
192188
V(sent_shutdown_string, "sentShutdown") \

src/node.cc

Lines changed: 14 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -2270,25 +2270,22 @@ void MemoryUsage(const FunctionCallbackInfo<Value>& args) {
22702270
return env->ThrowUVException(err, "uv_resident_set_memory");
22712271
}
22722272

2273+
Isolate* isolate = env->isolate();
22732274
// V8 memory usage
22742275
HeapStatistics v8_heap_stats;
2275-
env->isolate()->GetHeapStatistics(&v8_heap_stats);
2276-
2277-
Local<Number> heap_total =
2278-
Number::New(env->isolate(), v8_heap_stats.total_heap_size());
2279-
Local<Number> heap_used =
2280-
Number::New(env->isolate(), v8_heap_stats.used_heap_size());
2281-
Local<Number> external_mem =
2282-
Number::New(env->isolate(),
2283-
env->isolate()->AdjustAmountOfExternalAllocatedMemory(0));
2284-
2285-
Local<Object> info = Object::New(env->isolate());
2286-
info->Set(env->rss_string(), Number::New(env->isolate(), rss));
2287-
info->Set(env->heap_total_string(), heap_total);
2288-
info->Set(env->heap_used_string(), heap_used);
2289-
info->Set(env->external_string(), external_mem);
2290-
2291-
args.GetReturnValue().Set(info);
2276+
isolate->GetHeapStatistics(&v8_heap_stats);
2277+
2278+
// Get the double array pointer from the Float64Array argument.
2279+
CHECK(args[0]->IsFloat64Array());
2280+
Local<Float64Array> array = args[0].As<Float64Array>();
2281+
CHECK_EQ(array->Length(), 4);
2282+
Local<ArrayBuffer> ab = array->Buffer();
2283+
double* fields = static_cast<double*>(ab->GetContents().Data());
2284+
2285+
fields[0] = rss;
2286+
fields[1] = v8_heap_stats.total_heap_size();
2287+
fields[2] = v8_heap_stats.used_heap_size();
2288+
fields[3] = isolate->AdjustAmountOfExternalAllocatedMemory(0);
22922289
}
22932290

22942291

0 commit comments

Comments
 (0)