Skip to content

Commit 00cae50

Browse files
committed
os: improve tmpdir performance
1 parent 3d954dc commit 00cae50

File tree

3 files changed

+58
-11
lines changed

3 files changed

+58
-11
lines changed

benchmark/os/tmpdir.js

+31
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
'use strict';
2+
3+
const common = require('../common.js');
4+
const { tmpdir } = require('os');
5+
const assert = require('assert');
6+
7+
const bench = common.createBenchmark(main, {
8+
n: [1e6],
9+
});
10+
11+
function main({ n }) {
12+
// Warm up.
13+
const length = 1024;
14+
const array = [];
15+
for (let i = 0; i < length; ++i) {
16+
array.push(tmpdir());
17+
}
18+
19+
bench.start();
20+
for (let i = 0; i < n; ++i) {
21+
const index = i % length;
22+
array[index] = tmpdir();
23+
}
24+
bench.end(n);
25+
26+
// Verify the entries to prevent dead code elimination from making
27+
// the benchmark invalid.
28+
for (let i = 0; i < length; ++i) {
29+
assert.strictEqual(typeof array[i], 'string');
30+
}
31+
}

lib/os.js

+5-11
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ const {
3131
SymbolToPrimitive,
3232
} = primordials;
3333

34-
const { safeGetenv } = internalBinding('credentials');
34+
const { getTempDir } = internalBinding('credentials');
3535
const constants = internalBinding('constants').os;
3636
const isWindows = process.platform === 'win32';
3737

@@ -179,24 +179,18 @@ platform[SymbolToPrimitive] = () => process.platform;
179179
* @returns {string}
180180
*/
181181
function tmpdir() {
182-
let path;
183182
if (isWindows) {
184-
path = process.env.TEMP ||
183+
let path = process.env.TEMP ||
185184
process.env.TMP ||
186185
(process.env.SystemRoot || process.env.windir) + '\\temp';
187186
if (path.length > 1 && StringPrototypeEndsWith(path, '\\') &&
188187
!StringPrototypeEndsWith(path, ':\\'))
189188
path = StringPrototypeSlice(path, 0, -1);
190-
} else {
191-
path = safeGetenv('TMPDIR') ||
192-
safeGetenv('TMP') ||
193-
safeGetenv('TEMP') ||
194-
'/tmp';
195-
if (path.length > 1 && StringPrototypeEndsWith(path, '/'))
196-
path = StringPrototypeSlice(path, 0, -1);
189+
190+
return path;
197191
}
198192

199-
return path;
193+
return getTempDir();
200194
}
201195
tmpdir[SymbolToPrimitive] = () => tmpdir();
202196

src/node_credentials.cc

+22
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,26 @@ static void SafeGetenv(const FunctionCallbackInfo<Value>& args) {
109109
args.GetReturnValue().Set(result);
110110
}
111111

112+
static void GetTempDir(const FunctionCallbackInfo<Value>& args) {
113+
Environment* env = Environment::GetCurrent(args);
114+
Isolate* isolate = env->isolate();
115+
116+
std::string dir;
117+
if (!SafeGetenv("TMPDIR", &dir, env->env_vars()) &&
118+
!SafeGetenv("TMP", &dir, env->env_vars()) &&
119+
!SafeGetenv("TEMP", &dir, env->env_vars())) {
120+
dir = "/tmp";
121+
}
122+
123+
if (dir.size() > 1 && dir.ends_with("/")) {
124+
dir.pop_back();
125+
}
126+
127+
Local<Value> result =
128+
ToV8Value(isolate->GetCurrentContext(), dir).ToLocalChecked();
129+
args.GetReturnValue().Set(result);
130+
}
131+
112132
#ifdef NODE_IMPLEMENTS_POSIX_CREDENTIALS
113133

114134
static const uid_t uid_not_found = static_cast<uid_t>(-1);
@@ -456,6 +476,7 @@ static void InitGroups(const FunctionCallbackInfo<Value>& args) {
456476

457477
void RegisterExternalReferences(ExternalReferenceRegistry* registry) {
458478
registry->Register(SafeGetenv);
479+
registry->Register(GetTempDir);
459480

460481
#ifdef NODE_IMPLEMENTS_POSIX_CREDENTIALS
461482
registry->Register(GetUid);
@@ -478,6 +499,7 @@ static void Initialize(Local<Object> target,
478499
Local<Context> context,
479500
void* priv) {
480501
SetMethod(context, target, "safeGetenv", SafeGetenv);
502+
SetMethod(context, target, "getTempDir", GetTempDir);
481503

482504
#ifdef NODE_IMPLEMENTS_POSIX_CREDENTIALS
483505
Environment* env = Environment::GetCurrent(context);

0 commit comments

Comments
 (0)