Skip to content

Commit 12eab29

Browse files
committed
netlink: reduce allocations in marshalMessages
Reduce allocations in marshalMessages by summing their sizes and then allocating a single buffer to write directly to via a new marshalInto method. │ before │ after │ │ sec/op │ sec/op vs base │ MarshalMessages/1-12 60.35µ ± 4% 33.61µ ± 3% -44.32% (p=0.000 n=10) MarshalMessages/8-12 1537.5µ ± 4% 330.9µ ± 11% -78.47% (p=0.000 n=10) MarshalMessages/64-12 15.403m ± 5% 1.294m ± 3% -91.60% (p=0.000 n=10) MarshalMessages/512-12 74.14m ± 17% 11.84m ± 4% -84.03% (p=0.000 n=10) geomean 3.208m 642.5µ -79.98% │ before │ after │ │ B/op │ B/op vs base │ MarshalMessages/1-12 144.00Ki ± 0% 72.00Ki ± 0% -50.00% (p=0.000 n=10) MarshalMessages/8-12 2760.0Ki ± 0% 520.0Ki ± 0% -81.16% (p=0.000 n=10) MarshalMessages/64-12 25.719Mi ± 0% 4.008Mi ± 0% -84.42% (p=0.000 n=10) MarshalMessages/512-12 200.43Mi ± 0% 32.01Mi ± 0% -84.03% (p=0.000 n=10) geomean 6.648Mi 1.463Mi -78.00% │ before │ after │ │ allocs/op │ allocs/op vs base │ MarshalMessages/1-12 2.000 ± 0% 1.000 ± 0% -50.00% (p=0.000 n=10) MarshalMessages/8-12 15.000 ± 0% 1.000 ± 0% -93.33% (p=0.000 n=10) MarshalMessages/64-12 80.000 ± 0% 1.000 ± 0% -98.75% (p=0.000 n=10) MarshalMessages/512-12 537.000 ± 0% 1.000 ± 0% -99.81% (p=0.000 n=10) geomean 33.69 1.000 -97.03% See #254
1 parent 373849e commit 12eab29

1 file changed

Lines changed: 21 additions & 8 deletions

File tree

message.go

Lines changed: 21 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -210,27 +210,40 @@ func (m Message) MarshalBinary() ([]byte, error) {
210210
}
211211

212212
b := make([]byte, ml)
213+
m.marshalInto(b)
213214

215+
return b, nil
216+
}
217+
218+
// marshalInto marshals a Message into the supplied byte slice.
219+
func (m Message) marshalInto(b []byte) {
214220
binary.NativeEndian.PutUint32(b[0:], m.Header.Length)
215221
binary.NativeEndian.PutUint16(b[4:], uint16(m.Header.Type))
216222
binary.NativeEndian.PutUint16(b[6:], uint16(m.Header.Flags))
217223
binary.NativeEndian.PutUint32(b[8:], m.Header.Sequence)
218224
binary.NativeEndian.PutUint32(b[12:], m.Header.PID)
219-
copy(b[16:], m.Data)
220-
221-
return b, nil
225+
copy(b[nlmsgHeaderLen:], m.Data)
222226
}
223227

224228
// marshalMessages serializes multiple messages into a single byte slice.
225229
func marshalMessages(messages []Message) ([]byte, error) {
226-
var buf []byte
230+
var total int
227231
for _, m := range messages {
228-
b, err := m.MarshalBinary()
229-
if err != nil {
230-
return nil, err
232+
ml := nlmsgAlign(int(m.Header.Length))
233+
if ml < nlmsgHeaderLen || ml != int(m.Header.Length) {
234+
return nil, errIncorrectMessageLength
231235
}
232-
buf = append(buf, b...)
236+
total += ml
233237
}
238+
239+
buf := make([]byte, total)
240+
var offset int
241+
for _, m := range messages {
242+
ml := nlmsgAlign(int(m.Header.Length))
243+
m.marshalInto(buf[offset:])
244+
offset += ml
245+
}
246+
234247
return buf, nil
235248
}
236249

0 commit comments

Comments
 (0)