Skip to content

Commit d475db9

Browse files
authored
Merge pull request #5 from waterlinked/master
Improve performance by preallocating the output buffer
2 parents 89499e0 + 890bc78 commit d475db9

2 files changed

Lines changed: 45 additions & 2 deletions

File tree

cobs.go

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,9 @@ func TrimNull(p []byte) []byte {
3535
}
3636

3737
// Encode a null-terminated slice of bytes to a cobs frame
38-
func Encode(p []byte) (b []byte) {
38+
func Encode(p []byte) []byte {
39+
// preallocate output buffer with estimated size
40+
b := make([]byte, 0, EncodedSize(len(p)))
3941
var x [0xff]byte
4042
x[0] = 1
4143
for _, v := range p {
@@ -58,7 +60,9 @@ func Encode(p []byte) (b []byte) {
5860
}
5961

6062
// Decode a cobs frame to a null-terminated slice of bytes
61-
func Decode(p []byte) (b []byte) {
63+
func Decode(p []byte) []byte {
64+
// preallocate output buffer, data will be smaller than input
65+
b := make([]byte, 0, len(p))
6266
for len(p) > 0 {
6367
n, data := p[0], p[1:]
6468
// invalid frame, abort

cobs_test.go

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -388,3 +388,42 @@ func ExampleEncode() {
388388
// Hello: [6 72 101 108 108 111]
389389
// [6 72 101 108 108 111]: Hello
390390
}
391+
392+
func benchmarkEncode(i int, b *testing.B) {
393+
data := make([]byte, i)
394+
for i := range data {
395+
data[i] = byte(i % 255)
396+
}
397+
data[len(data)-1] = 0 // zero-terminate input
398+
399+
b.ResetTimer()
400+
for i := 0; i < b.N; i++ {
401+
Encode(data)
402+
}
403+
}
404+
405+
func benchmarkDecode(i int, b *testing.B) {
406+
data := make([]byte, i)
407+
for i := range data {
408+
data[i] = byte(i % 255)
409+
}
410+
data[len(data)-1] = 0 // zero-terminate input
411+
enc := Encode(data)
412+
413+
b.ResetTimer()
414+
for i := 0; i < b.N; i++ {
415+
Decode(enc)
416+
}
417+
}
418+
419+
func BenchmarkCobs(b *testing.B) {
420+
cases := []int{32, 256, 1024, 4096}
421+
for _, c := range cases {
422+
b.Run(fmt.Sprintf("%d/Encode", c), func(b *testing.B) {
423+
benchmarkEncode(c, b)
424+
})
425+
b.Run(fmt.Sprintf("%d/Decode", c), func(b *testing.B) {
426+
benchmarkDecode(c, b)
427+
})
428+
}
429+
}

0 commit comments

Comments
 (0)