-
Notifications
You must be signed in to change notification settings - Fork 499
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
Improve performance of XDR codec #2689
Comments
Moving to xdrpp is a medium term thing we would like to do. Would be great to evaluate to what extent that can be done while minimising API breakage. |
I'm looking into improving the Out of curiosity I did some quick benchmarks of the However, after benchmarking it is not clear to me that switching to A quick benchmark using an average sized transaction from pubnet showed that our existing xdr package is faster, and produces less allocations, when unmarshaling even though it uses reflection. The gxdr package is a little faster and produces less allocations when marshaling. This definitely needs more analysis and with some profiling there might be some low hanging fruit that makes either implementation much better.
benchmark_test.go testing xdr (xdrgen) vs gxdr (goxdr)package benchmarks
import (
"bytes"
"encoding/base64"
"testing"
"github.com/stellar/go/gxdr"
"github.com/stellar/go/xdr"
"github.com/stretchr/testify/require"
goxdr "github.com/xdrpp/goxdr/xdr"
)
const input64 = "AAAAAgAAAADy2f6v1nv9lXdvl5iZvWKywlPQYsZ1JGmmAfewflnbUAAABLACG4bdAADOYQAAAAEAAAAAAAAAAAAAAABhSLZ9AAAAAAAAAAEAAAABAAAAAF8wDgs7+R5R2uftMvvhHliZOyhZOQWsWr18/Fu6S+g0AAAAAwAAAAJHRE9HRQAAAAAAAAAAAAAAUwsPRQlK+jECWsJLURlsP0qsbA/aIaB/z50U79VSRYsAAAAAAAAAAAAAAYMAAA5xAvrwgAAAAAAAAAAAAAAAAAAAAAJ+WdtQAAAAQCTonAxUHyuVsmaSeGYuVsGRXgxs+wXvKgSa+dapZWN4U9sxGPuApjiv/UWb47SwuFQ+q40bfkPYT1Tff4RfLQe6S+g0AAAAQBlFjwF/wpGr+DWbjCyuolgM1VP/e4ubfUlVnDAdFjJUIIzVakZcr5omRSnr7ClrwEoPj49h+vcLusagC4xFJgg="
var input = func() []byte {
input, err := base64.StdEncoding.DecodeString(input64)
if err != nil {
panic(err)
}
return input
}()
func BenchmarkXDRUnmarshal(b *testing.B) {
te := xdr.TransactionEnvelope{}
// Make sure the input is valid.
err := te.UnmarshalBinary(input)
require.NoError(b, err)
// Benchmark.
for i := 0; i < b.N; i++ {
_ = te.UnmarshalBinary(input)
}
}
func BenchmarkGXDRUnmarshal(b *testing.B) {
te := gxdr.TransactionEnvelope{}
// Make sure the input is valid, note goxdr will panic if there's a
// marshaling error.
te.XdrMarshal(&goxdr.XdrIn{In: bytes.NewReader(input)}, "")
// Benchmark.
r := bytes.NewReader(input)
for i := 0; i < b.N; i++ {
r.Reset(input)
te.XdrMarshal(&goxdr.XdrIn{In: r}, "")
}
}
func BenchmarkXDRMarshal(b *testing.B) {
te := xdr.TransactionEnvelope{}
// Make sure the input is valid.
err := te.UnmarshalBinary(input)
require.NoError(b, err)
output, err := te.MarshalBinary()
require.NoError(b, err)
require.Equal(b, input, output)
// Benchmark.
for i := 0; i < b.N; i++ {
_, _ = te.MarshalBinary()
}
}
func BenchmarkGXDRMarshal(b *testing.B) {
te := gxdr.TransactionEnvelope{}
// Make sure the input is valid, note goxdr will panic if there's a
// marshaling error.
te.XdrMarshal(&goxdr.XdrIn{In: bytes.NewReader(input)}, "")
output := bytes.Buffer{}
te.XdrMarshal(&goxdr.XdrOut{Out: &output}, "")
// Benchmark.
for i := 0; i < b.N; i++ {
output.Reset()
te.XdrMarshal(&goxdr.XdrOut{Out: &output}, "")
}
} |
For context, after all the improvements we've got:
For marshalling (old = BenchmarkXDRUnmarshalWithReflection, new = BenchmarkXDRMarshalWithEncodingBuffer) , we have about a 30x speedup, 172x less memory allocated, 185x less allocations For unmarhsalling (old = BenchmarkXDRMarshalWithReflection-8 , new = BenchmarkXDRMarshalWithReflection-8 ), we have about a 11x speedup, 5x less memory allocated, 26x less allocations |
As we can see in #2552 , the performance encoding and decoding performance of the current codec (https://github.com/stellar/go-xdr) could be greatly improved by:
Horizon would greatly benefit from this.
As an alternative, there is https://github.com/xdrpp/goxdr (and https://github.com/calmh/xdr , but it's unmaintained )
The text was updated successfully, but these errors were encountered: