-
Notifications
You must be signed in to change notification settings - Fork 49
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
Ensure fixed-opaque types (arrays) implement EncodeTo() by pointer #68
Conversation
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.
Looks good. One request to change (❗) below, and a suggestion (💡).
I recommend testing the stellar/go tests before merging. Also last time we made a change @bartekn recommended running verify range on Horizon for a few days.
# Implement EncodeTo by pointer in fixed opaque types (arrays) | ||
# otherwise (if called by value), Go will make a heap allocation |
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.
💡 Suggested rewording of this explanation:
# Implement EncodeTo by pointer in fixed opaque types (arrays) | |
# otherwise (if called by value), Go will make a heap allocation | |
# Make the receiver of EncodeTo a pointer in fixed opaque types (arrays) | |
# otherwise (if called by value), Go will make a heap allocation |
I run the tests and they work
I don't think it will be necessary this time since the changes to diff --git a/xdr/xdr_generated.go b/xdr/xdr_generated.go
index 0add7f20..8dc1e82c 100644
--- a/xdr/xdr_generated.go
+++ b/xdr/xdr_generated.go
@@ -1064,7 +1064,7 @@ func (e Thresholds) XDRMaxSize() int {
}
// EncodeTo encodes this value using the Encoder.
-func (s Thresholds) EncodeTo(e *xdr.Encoder) error {
+func (s *Thresholds) EncodeTo(e *xdr.Encoder) error {
var err error
_, err = e.EncodeFixedOpaque(s[:])
if err != nil {
@@ -1327,7 +1327,7 @@ type PoolId Hash
// EncodeTo encodes this value using the Encoder.
func (s PoolId) EncodeTo(e *xdr.Encoder) error {
var err error
- err = Hash(s).EncodeTo(e)
+ err = (*Hash)(&s).EncodeTo(e)
if err != nil {
return err
}
@@ -1371,7 +1371,7 @@ func (e AssetCode4) XDRMaxSize() int {
}
// EncodeTo encodes this value using the Encoder.
-func (s AssetCode4) EncodeTo(e *xdr.Encoder) error {
+func (s *AssetCode4) EncodeTo(e *xdr.Encoder) error {
var err error
_, err = e.EncodeFixedOpaque(s[:])
if err != nil {
@@ -1417,7 +1417,7 @@ func (e AssetCode12) XDRMaxSize() int {
}
// EncodeTo encodes this value using the Encoder.
-func (s AssetCode12) EncodeTo(e *xdr.Encoder) error {
+func (s *AssetCode12) EncodeTo(e *xdr.Encoder) error {
var err error
_, err = e.EncodeFixedOpaque(s[:])
if err != nil {
@@ -25927,7 +25927,7 @@ func (e Hash) XDRMaxSize() int {
}
// EncodeTo encodes this value using the Encoder.
-func (s Hash) EncodeTo(e *xdr.Encoder) error {
+func (s *Hash) EncodeTo(e *xdr.Encoder) error {
var err error
_, err = e.EncodeFixedOpaque(s[:])
if err != nil {
@@ -25973,7 +25973,7 @@ func (e Uint256) XDRMaxSize() int {
}
// EncodeTo encodes this value using the Encoder.
-func (s Uint256) EncodeTo(e *xdr.Encoder) error {
+func (s *Uint256) EncodeTo(e *xdr.Encoder) error {
var err error
_, err = e.EncodeFixedOpaque(s[:])
if err != nil {
@@ -26747,7 +26747,7 @@ func (e SignatureHint) XDRMaxSize() int {
}
// EncodeTo encodes this value using the Encoder.
-func (s SignatureHint) EncodeTo(e *xdr.Encoder) error {
+func (s *SignatureHint) EncodeTo(e *xdr.Encoder) error {
var err error
_, err = e.EncodeFixedOpaque(s[:])
if err != nil {
|
The diff you posted was so useful in understanding the change that I think we should add a CI run that runs against stellar/go and prints out the diff. I created #69. |
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'm surprised this causes such a huge gain, because I would have thought the pointer receivers increase the change something gets moved to the stack. Happy to be wrong about this. Nice find!
This PR switches the
EncodeTo()
implementation for fixed opaque types (Go arrays) to a pointer received.Otherwise (if called by value), Go will make a heap allocation for every by-value call since the copy required by the call tends to escape the stack due to the large array sizes.
This finally reduces marhsalling allocations to a bare minimum and speeds up marshaling between 20 and 40%.
Using the benchmarks from stellar/go:
Before:
After: