-
Notifications
You must be signed in to change notification settings - Fork 29.9k
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: replace macro with lambda #13676
Conversation
Does this bring any performance impact? |
V(dst[(*k)++] = ((hi & 0x03) << 6) | ((lo & 0x3F) >> 0)); | ||
#undef V | ||
return true; // Continue decoding. | ||
auto V = [&](auto expr) { |
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.
😢
In file included from ../src/inspector_socket.cc:6:0:
../src/base64.h: In function ‘bool node::base64_decode_group_slow(char*, size_t, const TypeName*, size_t, size_t*, size_t*)’:
../src/base64.h:60:16: error: use of ‘auto’ in lambda parameter declaration only available with -std=c++14 or -std=gnu++14
auto V = [&](auto expr) {
^~~~
I’m not sure what to do about that. :/
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.
According to http://en.cppreference.com/w/cpp/compiler_support, polymorphic lambdas have been supported in GCC starting with version 4.9, which was released on April 22, 2014. Any reason why we can't require a compiler that's less than 3 years old?
According to this answer, -std=c++14
is supported in GCC from 5.2, but we can use -std=c++1y
instead.
(edited to include benchmark results from other platforms) Windows 7, VS2015
Windows 10, VS2015
Linux, gcc 4.9.1
macOS, Apple LLVM version 8.1.0 (clang-802.0.42)
|
@seishun I wouldn't call 25% performance decrease insignificant... |
I think I saw talk about raising the minimum to GCC 4.8 somewhere; but tbh I can’t really say how much of an impact bumping the requirements to C++14 would have. |
@evanlucas Well, zero-filling buffers caused about 50% performance decrease on average (#12141 (comment)) and I don't see anyone complaining about that. And I'd assume that API is used much more frequently than base64 decoding. @addaleax GCC 4.8 is already required, but there's a PR to raise that to 4.9: #13466. |
@seishun there is also a way to prevent that from happening ( -1 from me unless the performance impact no longer exists |
That's not exactly a trivial change, considering it affected dependencies too, so the existence of an alternative API doesn't really change anything.
Are you also using Windows? If not, can you provide benchmark results on your platform as well? GCC and clang might be better at optimizing this. |
But zero-filling buffers is a security fix. This is for debugging and readability. I don't think those things are comparable. cc/ @nodejs/performance for the question of whether we care about this perf regression (and whether it's just on Windows). I have no opinion on that (no idea how often this gets used). |
Some of us did complain about it (when it became the default). Anyway, I am also -1 on this if there is a performance regression and the change is not absolutely necessary. |
I'm more in the JS side of performance - but as a user of Node who encodes base64 a lot, I definitely care about this change. As a project collaborator - we haven't merged PRs for -2% performance regressions in |
I do not see how this is relevant to this discussion. BTW, I'm 👎 for this change to land if there is any decrease in performance. |
Since no one else did, I benchmarked this on Linux (gcc 4.9.1):
I'd assume the difference is even less noticeable with newer compilers. I have no idea why Also note that
I meant end users.
As someone who has fixed base64 decoding twice (#11995, #13660), I can tell first hand how painful it is to debug functions with macros. In fact, I changed it to a lambda while investigating the latter issue to make my life easier. Sure, it's not as important as security, but let's not dismiss the fact that it significantly raises the barrier for contributions. |
I'm +10 on debuggable and easier to reason about P.S. the picture on linux looks much better
p values show insignificance except for |
(I believe this translates to vanilla clang 3.9.x, but I'm not sure.)
After applying this patch: diff --git a/src/base64.h b/src/base64.h
index 39a8ccf196..07053af955 100644
--- a/src/base64.h
+++ b/src/base64.h
@@ -5,6 +5,7 @@
#include "util.h"
+#include <functional>
#include <stddef.h>
namespace node {
@@ -57,7 +58,7 @@ bool base64_decode_group_slow(char* const dst, const size_t dstlen,
size_t* const i, size_t* const k) {
uint8_t hi;
uint8_t lo;
- auto V = [&](auto expr) {
+ auto V = [&](std::function<void()> expr) {
for (;;) {
const uint8_t c = src[*i];
lo = unbase64(c); it compiles, but I get the following benchmark results (comparing against
|
@aqrln Well yes, it would certainly be much slower with |
Different code paths in debug vs release is a terrible idea. |
@seishun hmm, yes, that's better :D
|
@bnoordhuis, Ack. |
Killed https://ci.nodejs.org/job/node-test-pull-request/8697/ that has been running for 3h |
Interesting. I wonder if it's because of the |
It didn't hang, was just SUPER slow (I watched it for a while) |
I see. Let's just hope it's fixed in a newer GCC version. (See #13466 (comment)) |
CI https://ci.nodejs.org/job/node-test-pull-request/9934/ @nodejs/collaborators PTAL |
After reading the above -1 |
@BridgeAR did you mean to post a CI there? |
@benjamingr yes, thanks. I updated the link. The tests are failing badly. Probably older GCC versions? I did not look further into it. In general I feel there is little chance that this will land as there are multiple -1. |
Yes, some test machines use gcc versions older than the required 4.9.4. I've been working on that for the last 1.5 months, see nodejs/build#797 and nodejs/build#809.
It seems all of them are caused by the performance issue on Windows, so it'll probably have to wait until Microsoft improves their compiler. |
@seishun You’re right, I think this would have to wait for that – the question is, do you really want to wait until that happens + we make that new compiler version our supported baseline? Edit: Like, that is totally your choice. But I think those would be the prerequisites for this landing. |
What's the alternative, forget about this? |
@seishun Yeah, I think so. :( Or maybe leave a |
You can also ask for a CTC vote on this - but I'm afraid it'll be a hard sell since the current objections raised by reviewers are valid - and people won't buy "some nicer code" in exchange for compiler support. I really appreciate the effort by the way. |
I am closing this due to the mentioned reasons and the multiple -1. |
Makes it debuggable and easier to reason about.
Makes it debuggable and easier to reason about.
I'm not sure if it would be worthwhile to replace
V([] {})
withV([&] {})
for consistency. Also, couldn't find any other usages of parameterless lambdas in the codebase, so I'm not sure if this is the right style. (as opposed to[]{}
, without a space)Checklist
make -j4 test
(UNIX), orvcbuild test
(Windows) passesAffected core subsystem(s)
src