From e3dfd8889315af38c4eef1eb4247dc07a51899c7 Mon Sep 17 00:00:00 2001 From: kim Date: Tue, 29 Jul 2025 09:23:20 +0200 Subject: [performance] bump codeberg.org/gruf/go-kv to v2 (#4341) updates our codeberg.org/gruf/go-kv log key-value formatting library to latest version, which comes with some maaaaaaajor speed boosts in the form of: - very minimal reflect.Value{} usage - caching prepared formatting functions per type ~~still a work-in-progress until i make a release tag on the go-kv repository, which itself is waiting on published benchmark results in the README and finishing writing some code comments~~ benchmarks so far show this to be ~3x faster than the "fmt" stdlib package on average, when run across a wide variety (106 different types) of test cases, while still creating more visually friendly log output and actually recursing down nested struct ptrs Reviewed-on: https://codeberg.org/superseriousbusiness/gotosocial/pulls/4341 Co-authored-by: kim Co-committed-by: kim --- vendor/codeberg.org/gruf/go-kv/v2/format/abi.go | 262 ++++++++++++++++++++++++ 1 file changed, 262 insertions(+) create mode 100644 vendor/codeberg.org/gruf/go-kv/v2/format/abi.go (limited to 'vendor/codeberg.org/gruf/go-kv/v2/format/abi.go') diff --git a/vendor/codeberg.org/gruf/go-kv/v2/format/abi.go b/vendor/codeberg.org/gruf/go-kv/v2/format/abi.go new file mode 100644 index 000000000..815660a5e --- /dev/null +++ b/vendor/codeberg.org/gruf/go-kv/v2/format/abi.go @@ -0,0 +1,262 @@ +//go:build go1.24 && !go1.25 + +package format + +import ( + "reflect" + "unsafe" +) + +const ( + // see: go/src/internal/abi/type.go + abi_KindDirectIface uint8 = 1 << 5 + abi_KindMask uint8 = (1 << 5) - 1 +) + +// abi_Type is a copy of the memory layout of abi.Type{}. +// +// see: go/src/internal/abi/type.go +type abi_Type struct { + _ uintptr + PtrBytes uintptr + _ uint32 + _ uint8 + _ uint8 + _ uint8 + Kind_ uint8 + _ func(unsafe.Pointer, unsafe.Pointer) bool + _ *byte + _ int32 + _ int32 +} + +// abi_EmptyInterface is a copy of the memory layout of abi.EmptyInterface{}, +// which is to say also the memory layout of any method-less interface. +// +// see: go/src/internal/abi/iface.go +type abi_EmptyInterface struct { + Type *abi_Type + Data unsafe.Pointer +} + +// see: go/src/internal/abi/type.go Type.Kind() +func abi_Type_Kind(t reflect.Type) uint8 { + iface := (*reflect_nonEmptyInterface)(unsafe.Pointer(&t)) + atype := (*abi_Type)(unsafe.Pointer(iface.word)) + return atype.Kind_ & abi_KindMask +} + +// see: go/src/internal/abi/type.go Type.IfaceIndir() +func abi_Type_IfaceIndir(t reflect.Type) bool { + iface := (*reflect_nonEmptyInterface)(unsafe.Pointer(&t)) + atype := (*abi_Type)(unsafe.Pointer(iface.word)) + return atype.Kind_&abi_KindDirectIface == 0 +} + +// pack_iface packs a new reflect.nonEmptyInterface{} using shielded itab +// pointer and data (word) pointer, returning a pointer for caller casting. +func pack_iface(itab uintptr, word unsafe.Pointer) unsafe.Pointer { + return unsafe.Pointer(&reflect_nonEmptyInterface{ + itab: itab, + word: word, + }) +} + +// get_iface_ITab generates a new value of given type, +// casts it to the generic param interface type, and +// returns the .itab portion of the reflect.nonEmptyInterface{}. +// this is useful for later calls to pack_iface for known type. +func get_iface_ITab[I any](t reflect.Type) uintptr { + s := reflect.New(t).Elem().Interface().(I) + i := (*reflect_nonEmptyInterface)(unsafe.Pointer(&s)) + return i.itab +} + +// unpack_eface returns the .Data portion of an abi.EmptyInterface{}. +func unpack_eface(a any) unsafe.Pointer { + return (*abi_EmptyInterface)(unsafe.Pointer((&a))).Data +} + +// add returns the ptr addition of starting ptr and a delta. +func add(ptr unsafe.Pointer, delta uintptr) unsafe.Pointer { + return unsafe.Pointer(uintptr(ptr) + delta) +} + +// typeof is short-hand for reflect.TypeFor[T](). +func typeof[T any]() reflect.Type { + return reflect.TypeFor[T]() +} + +// see: go/src/reflect/value.go +type reflect_flag uintptr + +const ( + // see: go/src/reflect/value.go + reflect_flagKindWidth = 5 // there are 27 kinds + reflect_flagKindMask reflect_flag = 1<