Skip to content

Commit 3149021

Browse files
authored
Do not copy PathElems when creating a map value's path. (#609)
Before BenchmarkNotificationOutput-12 10000 107130 ns/op BenchmarkNotificationOutputElement-12 14344 83329 ns/op After BenchmarkNotificationOutput-12 12613 95651 ns/op BenchmarkNotificationOutputElement-12 14298 84451 ns/op
1 parent 032d1f4 commit 3149021

File tree

2 files changed

+39
-5
lines changed

2 files changed

+39
-5
lines changed

ygot/render.go

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -462,13 +462,14 @@ func findUpdatedLeaves(leaves map[*path]interface{}, s GoStruct, parent *gnmiPat
462462
// key and value. The format of the path returned depends on the input format
463463
// of the parentPath.
464464
func mapValuePath(key, value reflect.Value, parentPath *gnmiPath) (*gnmiPath, error) {
465-
childPath := &gnmiPath{}
465+
var childPath *gnmiPath
466466

467467
if parentPath == nil {
468468
return nil, fmt.Errorf("nil map paths supplied to mapValuePath for %v %v", key.Interface(), value.Interface())
469469
}
470470

471471
if parentPath.isStringSlicePath() {
472+
childPath = &gnmiPath{}
472473
keyval, err := KeyValueAsString(key.Interface())
473474
if err != nil {
474475
return nil, fmt.Errorf("can't append path element key: %v", err)
@@ -480,10 +481,8 @@ func mapValuePath(key, value reflect.Value, parentPath *gnmiPath) (*gnmiPath, er
480481
return childPath, nil
481482
}
482483

483-
for _, e := range parentPath.pathElemPath {
484-
n := proto.Clone(e).(*gnmipb.PathElem)
485-
childPath.pathElemPath = append(childPath.pathElemPath, n)
486-
}
484+
// Only the pointer values are copied for performance.
485+
childPath = parentPath.Copy()
487486

488487
return appendgNMIPathElemKey(value, childPath)
489488
}

ygot/schema_tests/schema_test.go

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -490,3 +490,38 @@ func TestNotificationOutput(t *testing.T) {
490490
})
491491
}
492492
}
493+
494+
func getBenchmarkDevice() *exampleoc.Device {
495+
intfs := []string{"eth0", "eth1", "eth2", "eth3"}
496+
d := &exampleoc.Device{}
497+
for _, intf := range intfs {
498+
d.GetOrCreateInterface(intf)
499+
is := d.GetOrCreateLldp().GetOrCreateInterface(intf).GetOrCreateNeighbor("neighbor")
500+
is.LastUpdate = ygot.Int64(42)
501+
}
502+
return d
503+
}
504+
505+
func BenchmarkNotificationOutput(b *testing.B) {
506+
d := getBenchmarkDevice()
507+
b.ResetTimer()
508+
for i := 0; i != b.N; i++ {
509+
if _, err := ygot.TogNMINotifications(d, 0, ygot.GNMINotificationsConfig{
510+
UsePathElem: true,
511+
}); err != nil {
512+
b.Fatalf("cannot marshal input to gNMI Notifications, %v", err)
513+
}
514+
}
515+
}
516+
517+
func BenchmarkNotificationOutputElement(b *testing.B) {
518+
d := getBenchmarkDevice()
519+
b.ResetTimer()
520+
for i := 0; i != b.N; i++ {
521+
if _, err := ygot.TogNMINotifications(d, 0, ygot.GNMINotificationsConfig{
522+
UsePathElem: false,
523+
}); err != nil {
524+
b.Fatalf("cannot marshal input to gNMI Notifications, %v", err)
525+
}
526+
}
527+
}

0 commit comments

Comments
 (0)