-
Notifications
You must be signed in to change notification settings - Fork 29.7k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
src: improve node:os
userInfo performance
#55719
Conversation
Codecov ReportAttention: Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## main #55719 +/- ##
==========================================
+ Coverage 88.38% 88.41% +0.02%
==========================================
Files 654 654
Lines 187575 187759 +184
Branches 36096 36126 +30
==========================================
+ Hits 165795 166012 +217
+ Misses 15004 14996 -8
+ Partials 6776 6751 -25
|
55614e5
to
6d0bf5a
Compare
#ifdef _WIN32 | ||
Local<Value> uid = Number::New( | ||
env->isolate(), | ||
static_cast<double>(static_cast<int32_t>(pwd.uid & 0xFFFFFFFF))); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This has ben discussed and I don't want to block this... but this code might be too complicated. The following might suffice:
static_cast<double>(static_cast<int32_t>(pwd.uid & 0xFFFFFFFF))); | |
static_cast<double>(static_cast<int32_t>(pwd.uid))); |
So that I understand... we start with this...
typedef struct uv_passwd_s {
char* username;
long uid;
long gid;
char* shell;
char* homedir;
} uv_passwd_t;
(source: libuv documentation.)
Lines 1212 to 1218 in a243225
struct uv_passwd_s { | |
char* username; | |
unsigned long uid; | |
unsigned long gid; | |
char* shell; | |
char* homedir; | |
}; |
Under non-Windows systems.
But, for extra fun... under Windows, we have a different definition...
struct uv_passwd_s
{
char *username;
unsigned long uid;
unsigned long gid;
char *shell;
char *homedir;
};
A long in Visual Studio is effectively an int32_t
, it goes from -2,147,483,648 to 2,147,483,647. Whereas an unsigned long is an uint32_t.
Most other compiler systems will have long be either int32_t or int64_t (depending on whether we have a 32-bit or 64-bit system). They will have long be either uint32_t or uint64_t.
Now, Number::New's function signature takes a double. So the cast to double is mostly just to show what is happening (as it would happen implicitly).
So, setting aside the cast to double, we are doing...
uint32_t x =...
x = static_cast<int32_t>(x & 0xFFFFFFFF)
(If I got something wrong, please tell me.)
What is the purpose of the 0xFFFFFFFF
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I missed these reviews. I'll open another pull-request to apply the changes.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@anonrig That's fine. I think your code is correct. It was just nitpicking.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The purpose of & 0xFFFFFFFF
here was to mask higher bits. Unless my knowledge is horribly outdated, casting with overflow here would be UB (even though i doubt existence of implementations that don't just discard extra bits).
No strong opinion on casting to double
, except for 'explicit > implicit' rule of thumb.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The purpose of & 0xFFFFFFFF here was to mask higher bits. Unless my knowledge is horribly outdated, casting with overflow here would be UB
An unsigned long under Visual Studio is a 32-bit unsigned integer. So we are casting an uint32 to an int32.
https://learn.microsoft.com/en-us/cpp/cpp/data-type-ranges?view=msvc-170
Node is C++20 and in C++20 casting from unsigned to signed and back is well defined.
No strong opinion on casting to double, except for 'explicit > implicit' rule of thumb.
I do not care at all. I only remarked that @anonrig's code was not perfectly consistent. I did not ask for the code to change.
static_cast<double>(static_cast<int32_t>(pwd.uid & 0xFFFFFFFF))); | ||
Local<Value> gid = Number::New( | ||
env->isolate(), | ||
static_cast<double>(static_cast<int32_t>(pwd.gid & 0xFFFFFFFF))); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
static_cast<double>(static_cast<int32_t>(pwd.gid & 0xFFFFFFFF))); | |
static_cast<double>(static_cast<int32_t>(pwd.gid))); |
Local<Value> gid = Number::New( | ||
env->isolate(), | ||
static_cast<double>(static_cast<int32_t>(pwd.gid & 0xFFFFFFFF))); | ||
#else | ||
Local<Value> uid = Number::New(env->isolate(), pwd.uid); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The cast to double is implicit, but for Windows you make it explicit... if so then I would suggest making it explicit here:
Local<Value> uid = Number::New(env->isolate(), pwd.uid); | |
Local<Value> uid = Number::New(env->isolate(), static_cast<double>(pwd.uid)); |
Local<Value> gid = Number::New( | ||
env->isolate(), | ||
static_cast<double>(static_cast<int32_t>(pwd.gid & 0xFFFFFFFF))); | ||
#else | ||
Local<Value> uid = Number::New(env->isolate(), pwd.uid); | ||
Local<Value> gid = Number::New(env->isolate(), pwd.gid); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Local<Value> gid = Number::New(env->isolate(), pwd.gid); | |
Local<Value> gid = Number::New(env->isolate(), static_cast<double>(pwd.gid)); |
Landed in 58a8eb4 |
Improve
node:os
userInfo performance by reducing the cost of creating a v8::Object.