implement in-place decode#3
Conversation
| @@ -51,6 +51,7 @@ type Decoder interface { | |||
| // | |||
There was a problem hiding this comment.
The documentation for Decode() already mentions that it happens in place. Why a new function?
There was a problem hiding this comment.
Decode() uses copy operations, create new array, and copy backs to original array.
New function does not copy the array.
There was a problem hiding this comment.
Why not just change the original function and keep the same name?
There was a problem hiding this comment.
Original function takes two slices. Changed version takes one slice. I don't know changing that is okay.
If you think it is okay, I can just modify the original so that it takes one slice.
There was a problem hiding this comment.
Also I will update the decoder_test.go
There was a problem hiding this comment.
Its doing same job without copy operations, just knowing ecc count. We need one slice, because your poly struct has one slice. If we get two slices, we need to concat them to put inside the poly.
If we want to use two slices without copying them, we need to modify poly which I don't know how it works.
Here unmodified Decode
func (d *rSDecoder) Decode(data, ecc []byte) (int, error) {
// TODO(maruel): Temporary migration code.
received := make([]byte, len(data)+len(ecc))
copy(received, data)
copy(received[len(data):], ecc)
poly := &poly{d.f, received}
syndromeCoeffs := make([]byte, len(ecc))Here modified Decode
func (d *rSDecoder) Decode(dataWithEcc []byte, eccLen int) (int, error) {
// TODO(maruel): Temporary migration code.
dataLen := len(dataWithEcc) - eccLen
poly := &poly{d.f, dataWithEcc}
syndromeCoeffs := make([]byte, eccLen)In my case, I store and transmit data with ecc together, its better for me to call Decode(dataWithEcc, eccLen) instead of Decode(dataWithEcc[:dataLen], dataWithEcc[dataLen:])
There was a problem hiding this comment.
Using two slices permits to store the ecc in both a discontinuous or continuous stream. The new version is much more limiting here. I'd highly prefer to fix poly instead.
Slices are not arrays. A slice is a view into an array, thus there's no copy in the two slices version. See https://gobyexample.com/slices
There was a problem hiding this comment.
I don't mean passing slices are copy. I mean, you are calling copy function directly inside the Decode. And as I said we have to copy if we don't modify the poly.
I will look poly, maybe we can modify it so it also takes two slices.
There was a problem hiding this comment.
Yes modifying poly would be my preference.
There was a problem hiding this comment.
When I look the poly, it is using coefficients as a single slice. Converting it to multiple slices probably not a good idea.
type poly struct {
field *Field
coefficients []byte // In reverse order.
}
So, I am offering the code as I opened PR, we can add DecodeInPlace to code, (name can be change). and we can use Decode like the same. it probably does not create much overhead(i can do benchmark if you want), and if we want we can use DecodeInPlace which does 4 less copy operations.
func (d *rSDecoder) Decode(data, ecc []byte) (int, error) {
received := make([]byte, len(data)+len(ecc))
copy(received, data)
copy(received[len(data):], ecc)
errorCount, decodeError := d.DecodeInPlace(received, len(ecc))
copy(data, received)
copy(ecc, received[len(data):])
return errorCount, decodeError
}
|
Here Benchmark results, but I am not sure I benchmarked correctly and I don't know how to analyze this results. Old Decode New Decode |
|
I updated the benchmark with Old DecodeNew Decode |
|
Closing this one, we can continue on #4. |
I implement the in-place decode and add a test for it.