Uh oh!
There was an error while loading. Please reload this page.
src: replace macro with lambda - #13676
Conversation
evanlucas
commented
Jun 14, 2017
Does this bring any performance impact? |
There was a problem hiding this comment.
😢
In file included from ../src/inspector_socket.cc:6:0:
../src/base64.h: In function ‘boolnode::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.
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) |
evanlucas
commented
Jun 14, 2017
@seishun I wouldn't call 25% performance decrease insignificant... |
addaleax
commented
Jun 14, 2017
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. |
evanlucas
commented
Jun 14, 2017
@seishun there is also a way to prevent that from happening ( -1 from me unless the performance impact no longer exists |
seishun
commented
Jun 14, 2017
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. |
gibfahn
commented
Jun 14, 2017
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). |
mscdex
commented
Jun 14, 2017
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. |
benjamingr
commented
Jun 14, 2017
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 |
mcollina
commented
Jun 14, 2017
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. |
refack
commented
Jun 14, 2017
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 |
aqrln
commented
Jun 15, 2017
(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 |
seishun
commented
Jun 15, 2017
@aqrln Well yes, it would certainly be much slower with |
bnoordhuis
commented
Jun 15, 2017
Different code paths in debug vs release is a terrible idea. |
aqrln
commented
Jun 15, 2017
@seishun hmm, yes, that's better :D |
refack
commented
Jun 15, 2017
@bnoordhuis, Ack. |
seishun
commented
Jun 16, 2017
refack
commented
Jun 16, 2017
Killed https://ci.nodejs.org/job/node-test-pull-request/8697/ that has been running for 3h |
seishun
commented
Jun 16, 2017
Interesting. I wonder if it's because of the |
It didn't hang, was just SUPER slow (I watched it for a while) |
seishun
commented
Jun 16, 2017
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 |
eljefedelrodeodeljefe
commented
Sep 4, 2017
After reading the above -1 |
benjamingr
commented
Sep 4, 2017
@BridgeAR did you mean to post a CI there? |
BridgeAR
commented
Sep 4, 2017
@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. |
seishun
commented
Sep 4, 2017
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. |
seishun
commented
Sep 4, 2017
What's the alternative, forget about this? |
addaleax
commented
Sep 4, 2017
@seishun Yeah, I think so. :( Or maybe leave a |
benjamingr
commented
Sep 4, 2017
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. |
BridgeAR
commented
Sep 19, 2017
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