Added benchmark and comment about generic On/To pair

This commit is contained in:
Marius Orcsik 2022-06-04 16:35:11 +02:00
parent 07cf4a27c1
commit 6917e06269
No known key found for this signature in database
GPG key ID: DBF5E47F5DBC4D21
3 changed files with 87 additions and 6 deletions

View file

@ -15,3 +15,28 @@ They are documented accordingly with annotations from the specification.
```go
import "github.com/go-ap/activitypub"
```
## Note about generics
The helper functions exposed by the package come in two flavours:
explicit `OnXXX` and `ToXXX` functions corresponding to each type and,
a generic pair of functions `On[T]` and `To[T]`.
Before using them you should consider that the former comes with a pretty heavy performance penalty:
```
goos: linux
goarch: amd64
pkg: github.com/go-ap/activitypub
cpu: Intel(R) Core(TM) i7-6700K CPU @ 4.00GHz
Benchmark_OnT_vs_On_T/OnObject-8 752387791 1.633 ns/op
Benchmark_OnT_vs_On_T/On_T_Object-8 4656264 261.8 ns/op
Benchmark_OnT_vs_On_T/OnActor-8 739833261 1.596 ns/op
Benchmark_OnT_vs_On_T/On_T_Actor-8 4035148 301.9 ns/op
Benchmark_OnT_vs_On_T/OnActivity-8 751173854 1.604 ns/op
Benchmark_OnT_vs_On_T/On_T_Activity-8 4062598 285.9 ns/op
Benchmark_OnT_vs_On_T/OnIntransitiveActivity-8 675824500 1.640 ns/op
Benchmark_OnT_vs_On_T/On_T_IntransitiveActivity-8 4372798 274.1 ns/op
PASS
ok github.com/go-ap/activitypub 11.350s
```

View file

@ -55,17 +55,16 @@ func OnLink(it LinkOrIRI, fn WithLinkFn) error {
return fn(ob)
}
func To[T Objects](it Item) (*T, error) {
ob, ok := it.(T)
if !ok {
return nil, fmt.Errorf("invalid cast for object %T", it)
func To[T Item](it Item) (*T, error) {
if ob, ok := it.(T); ok {
return &ob, nil
}
return &ob, nil
return nil, fmt.Errorf("invalid cast for object %T", it)
}
// On handles in a generic way the call to fn(*T) if the "it" Item can be asserted to one of the Objects type.
// It also covers the case where "it" is a collection of items that match the assertion.
func On[T Objects](it Item, fn func(*T) error) error {
func On[T Item](it Item, fn func(*T) error) error {
if !IsItemCollection(it) {
ob, err := To[T](it)
if err != nil {

View file

@ -319,3 +319,60 @@ func TestOn(t *testing.T) {
})
}
}
var fnObj = func(_ *Object) error {
return nil
}
var fnAct = func(_ *Actor) error {
return nil
}
var fnA = func(_ *Activity) error {
return nil
}
var fnIA = func(_ *IntransitiveActivity) error {
return nil
}
func Benchmark_OnT_vs_On_T(b *testing.B) {
var it Item
b.Run("OnObject", func(b *testing.B) {
for i := 0; i < b.N; i++ {
OnObject(it, fnObj)
}
})
b.Run("On_T_Object", func(b *testing.B) {
for i := 0; i < b.N; i++ {
On[Object](it, fnObj)
}
})
b.Run("OnActor", func(b *testing.B) {
for i := 0; i < b.N; i++ {
OnActor(it, fnAct)
}
})
b.Run("On_T_Actor", func(b *testing.B) {
for i := 0; i < b.N; i++ {
On[Actor](it, fnAct)
}
})
b.Run("OnActivity", func(b *testing.B) {
for i := 0; i < b.N; i++ {
OnActivity(it, fnA)
}
})
b.Run("On_T_Activity", func(b *testing.B) {
for i := 0; i < b.N; i++ {
On[Activity](it, fnA)
}
})
b.Run("OnIntransitiveActivity", func(b *testing.B) {
for i := 0; i < b.N; i++ {
OnIntransitiveActivity(it, fnIA)
}
})
b.Run("On_T_IntransitiveActivity", func(b *testing.B) {
for i := 0; i < b.N; i++ {
On[IntransitiveActivity](it, fnIA)
}
})
}