~eliasnaur/gio-patches

gio: text: optimize faceCache.hashGIDs v1 PROPOSED

Dominik Honnef: 1
 text: optimize faceCache.hashGIDs

 1 files changed, 3 insertions(+), 1 deletions(-)
#789792 apple.yml success
#789793 freebsd.yml success
#789794 linux.yml failed
#789795 openbsd.yml success
"Sebastien Binet" <s@sbinet.org> writes:
Next
Export patchset (mbox)
How do I use this?

Copy & paste the following snippet into your terminal to import this patchset into git:

curl -s https://lists.sr.ht/~eliasnaur/gio-patches/patches/33352/mbox | git am -3
Learn more about email & git

[PATCH gio] text: optimize faceCache.hashGIDs Export this patch

Use binary.LittleEndian directly instead of going through the
binary.Write indirection. This allows the following optimizations to
occur:

  - We can reuse our own byte slice between iterations
  - We don't have to put g.ID in an interface value
  - h doesn't escape
  - PutUint32 gets inlined

On top of that, the argument to maphash.Hash.Write doesn't escape, so b
doesn't move to the heap.

Signed-off-by: Dominik Honnef <dominik@honnef.co>
---
 text/shaper.go | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/text/shaper.go b/text/shaper.go
index 338d215e..942c8097 100644
--- a/text/shaper.go
+++ b/text/shaper.go
@@ -156,8 +156,10 @@ func (f *faceCache) hashGIDs(layout Layout) uint64 {
	}
	var h maphash.Hash
	h.SetSeed(f.seed)
	var b [4]byte
	for _, g := range layout.Glyphs {
		binary.Write(&h, binary.LittleEndian, g.ID)
		binary.LittleEndian.PutUint32(b[:], uint32(g.ID))
		h.Write(b[:])
	}
	return h.Sum64()
}
-- 
2.36.1

gio/patches: FAILED in 19m26s

[text: optimize faceCache.hashGIDs][0] from [Dominik Honnef][1]

[0]: https://lists.sr.ht/~eliasnaur/gio-patches/patches/33352
[1]: mailto:dominik@honnef.co

✗ #789794 FAILED  gio/patches/linux.yml   https://builds.sr.ht/~eliasnaur/job/789794
✓ #789793 SUCCESS gio/patches/freebsd.yml https://builds.sr.ht/~eliasnaur/job/789793
✓ #789795 SUCCESS gio/patches/openbsd.yml https://builds.sr.ht/~eliasnaur/job/789795
✓ #789792 SUCCESS gio/patches/apple.yml   https://builds.sr.ht/~eliasnaur/job/789792
> Use binary.LittleEndian directly instead of going through the
> binary.Write indirection. This allows the following optimizations to
> occur:
> 
> - We can reuse our own byte slice between iterations
> - We don't have to put g.ID in an interface value
> - h doesn't escape
> - PutUint32 gets inlined
> 
> On top of that, the argument to maphash.Hash.Write doesn't escape, so b
> doesn't move to the heap.
> 
> Signed-off-by: Dominik Honnef <dominik@honnef.co>
> ---
> text/shaper.go | 4 +++-
> 1 file changed, 3 insertions(+), 1 deletion(-)
> 
> diff --git a/text/shaper.go b/text/shaper.go
> index 338d215e..942c8097 100644
> --- a/text/shaper.go
> +++ b/text/shaper.go
> @@ -156,8 +156,10 @@ func (f *faceCache) hashGIDs(layout Layout) uint64
> {
> }
> var h maphash.Hash
> h.SetSeed(f.seed)
> + var b [4]byte
b := make([]byte, 4)

instead?
> for _, g := range layout.Glyphs {
> - binary.Write(&h, binary.LittleEndian, g.ID)
> + binary.LittleEndian.PutUint32(b[:], uint32(g.ID))
and do:
 binary.LittleEndian.PutUint32(b, uint32(g.ID))
instead ?

(it used to be that slicing an array would incur a performance hit.)
Thanks, merged.

Elias