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
Improved efficiency in COutPoint constructors #10292
Conversation
src/primitives/transaction.h
Outdated
COutPoint() { SetNull(); } | ||
COutPoint(uint256 hashIn, uint32_t nIn) { hash = hashIn; n = nIn; } | ||
COutPoint(): n( (uint32_t) -1 ) { } | ||
COutPoint(const uint256& hash, uint32_t n): hash(hash), n(n) { } |
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.
Can you leave the names as hashIn
and nIn
so we don't get hash(hash), n(n)
?
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.
utACK with @kallewoof 's suggestion
src/primitives/transaction.h
Outdated
@@ -22,8 +22,8 @@ class COutPoint | |||
uint256 hash; | |||
uint32_t n; | |||
|
|||
COutPoint() { SetNull(); } | |||
COutPoint(uint256 hashIn, uint32_t nIn) { hash = hashIn; n = nIn; } | |||
COutPoint(): n( (uint32_t) -1 ) { } |
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.
Inconsistent spacing, n((uint32_t) -1)
is fine
Fixed both suggestions. @dcousens & @kallewoof, Thanks |
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.
utACK 4fbae77
I would argue that foo(foo) is less ambiguous despite semantic equivalence. It's also the standard that's been adhered to in the code thus far so it'd require some amount of merit to break. |
it is just that c(p):p(p) is a better abstraction than c(pIn):p(pIn) since In does not add any meaning to the code, apart from remarking that it is an input parameter which is obvious. |
That's all fine and dandy until you start doing things like class foo {
int x;
foo(int x) { x = x * 48; }
}; which, crazy as it may seem, is not very far away from your suggestion. |
Weak Concept Ack. Most likely this gets inlined and optimized out so this shouldn't impact the generated code? If that isn't the case, I have a slight preference to make this happen by exposing an uninitialized constructor for uin256_t and then calling SetNull. |
@JeremyRubin Not easy decision: The default constructor is reseting to 0, adding a constructor that leaves the object uninitalized looks like having an ugly prototype; on the other hand changing the behavior by leaving the object uninitalized in the default constructor and adding another constructor accepting a uint8[] looks like it is the right design, but at this point it may confuse to whom is already assuming that the default constructor is reseting the memory, apart from checking every single call done in the codebase. |
I'm not suggesting that it has to/should be the default constructor. Also the main part is that this likely does not impact the actual code generated; you should try outputting optimized assembly for #include <memory>
int main() {
char x[32];
memset((void*)*x, 0, 32);
} and #include <memory>
int main() {
char x[32];
memset((void*)*x, 0, 32);
memset((void*)*x, 0, 32);
} I didn't see a difference even at O1. |
@JeremyRubin Also when the code is split over different modules? |
@JeremyRubin The compiler can resolve programmer's errors automatically, but it is preferably to have the high level code well designed before the optimizer checks ; with so many compiler vendors , so many flags and so many archs out there you can never say for sure the compiler will end up optimizing. |
@sipa I think the memset occurs in the header so it's my understanding it would be inlined. edit: notice that memset is defined in a different header in my example. @mm-s while this is true, your PR is not fixing an error it is an optimization, which introduces a dependency on the 0 initialization of uint256 that might introduce bugs later. Perhaps one easy way is: class X {
public:
X(bool initialized=true) {
}
}; |
utACK 4fbae77 I think this change is perfectly reasonable. There is a slight duplication between the SetNull function and the constructor, but it comes at almost no extra complexity. Please let's not introduce explicit non-initializing constructors. |
4fbae77 Improved efficiency in COutPoint constructors (Marcos Mayorga) Tree-SHA512: 1e402d5021a47724b6159af90955f1a5932c383f48e3e704f1c9a52daa18d2dce5d8e1fcd02fae6977eab04ab83fa22872110b821d4c6593d940d9642abc9bcd
4fbae77 Improved efficiency in COutPoint constructors (Marcos Mayorga) Tree-SHA512: 1e402d5021a47724b6159af90955f1a5932c383f48e3e704f1c9a52daa18d2dce5d8e1fcd02fae6977eab04ab83fa22872110b821d4c6593d940d9642abc9bcd
4fbae77 Improved efficiency in COutPoint constructors (Marcos Mayorga) Tree-SHA512: 1e402d5021a47724b6159af90955f1a5932c383f48e3e704f1c9a52daa18d2dce5d8e1fcd02fae6977eab04ab83fa22872110b821d4c6593d940d9642abc9bcd
4fbae77 Improved efficiency in COutPoint constructors (Marcos Mayorga) Tree-SHA512: 1e402d5021a47724b6159af90955f1a5932c383f48e3e704f1c9a52daa18d2dce5d8e1fcd02fae6977eab04ab83fa22872110b821d4c6593d940d9642abc9bcd
4fbae77 Improved efficiency in COutPoint constructors (Marcos Mayorga) Tree-SHA512: 1e402d5021a47724b6159af90955f1a5932c383f48e3e704f1c9a52daa18d2dce5d8e1fcd02fae6977eab04ab83fa22872110b821d4c6593d940d9642abc9bcd
4fbae77 Improved efficiency in COutPoint constructors (Marcos Mayorga) Tree-SHA512: 1e402d5021a47724b6159af90955f1a5932c383f48e3e704f1c9a52daa18d2dce5d8e1fcd02fae6977eab04ab83fa22872110b821d4c6593d940d9642abc9bcd
4fbae77 Improved efficiency in COutPoint constructors (Marcos Mayorga) Tree-SHA512: 1e402d5021a47724b6159af90955f1a5932c383f48e3e704f1c9a52daa18d2dce5d8e1fcd02fae6977eab04ab83fa22872110b821d4c6593d940d9642abc9bcd
4fbae77 Improved efficiency in COutPoint constructors (Marcos Mayorga) Tree-SHA512: 1e402d5021a47724b6159af90955f1a5932c383f48e3e704f1c9a52daa18d2dce5d8e1fcd02fae6977eab04ab83fa22872110b821d4c6593d940d9642abc9bcd
4fbae77 Improved efficiency in COutPoint constructors (Marcos Mayorga) Tree-SHA512: 1e402d5021a47724b6159af90955f1a5932c383f48e3e704f1c9a52daa18d2dce5d8e1fcd02fae6977eab04ab83fa22872110b821d4c6593d940d9642abc9bcd
4fbae77 Improved efficiency in COutPoint constructors (Marcos Mayorga) Tree-SHA512: 1e402d5021a47724b6159af90955f1a5932c383f48e3e704f1c9a52daa18d2dce5d8e1fcd02fae6977eab04ab83fa22872110b821d4c6593d940d9642abc9bcd
4fbae77 Improved efficiency in COutPoint constructors (Marcos Mayorga) Tree-SHA512: 1e402d5021a47724b6159af90955f1a5932c383f48e3e704f1c9a52daa18d2dce5d8e1fcd02fae6977eab04ab83fa22872110b821d4c6593d940d9642abc9bcd
4fbae77 Improved efficiency in COutPoint constructors (Marcos Mayorga) Tree-SHA512: 1e402d5021a47724b6159af90955f1a5932c383f48e3e704f1c9a52daa18d2dce5d8e1fcd02fae6977eab04ab83fa22872110b821d4c6593d940d9642abc9bcd
4fbae77 Improved efficiency in COutPoint constructors (Marcos Mayorga) Tree-SHA512: 1e402d5021a47724b6159af90955f1a5932c383f48e3e704f1c9a52daa18d2dce5d8e1fcd02fae6977eab04ab83fa22872110b821d4c6593d940d9642abc9bcd
memset(0) executed twice, first in uint256_t default constructor and then in SetNull.
Remake of #10277