From 92ba5904c1645e6572f5ff1b9d0e0ec629e1afb9 Mon Sep 17 00:00:00 2001
From: Markus Wüstenberg
Date: Thu, 29 Oct 2020 15:40:14 +0100
Subject: Remove fmt.Sprintf call in attribute Render (#38)

Just concatenating the strings is much faster.

Before:

```
make benchmark
go test -bench=.
goos: darwin
goarch: amd64
pkg: github.com/maragudk/gomponents
BenchmarkAttr/boolean_attributes-8         	 8194791	       139 ns/op
BenchmarkAttr/name-value_attributes-8      	 5143292	       229 ns/op
PASS
ok  	github.com/maragudk/gomponents	2.841s
```

After:

```
make benchmark
go test -bench=.
goos: darwin
goarch: amd64
pkg: github.com/maragudk/gomponents
BenchmarkAttr/boolean_attributes-8         	16755404	        67.0 ns/op
BenchmarkAttr/name-value_attributes-8      	10208625	       116 ns/op
PASS
ok  	github.com/maragudk/gomponents	2.702s
```---
 Makefile           |  5 ++++-
 gomponents.go      |  4 ++--
 gomponents_test.go | 16 ++++++++++++++++
 3 files changed, 22 insertions(+), 3 deletions(-)

diff --git a/Makefile b/Makefile
index dc8bb1f..c453239 100644
--- a/Makefile
+++ b/Makefile
@@ -1,4 +1,7 @@
-.PHONY: cover lint test
+.PHONY: benchmark cover lint test
+
+benchmark:
+	go test -bench=.
 
 cover:
 	go tool cover -html=cover.out
diff --git a/gomponents.go b/gomponents.go
index e6b89e1..f4b8467 100644
--- a/gomponents.go
+++ b/gomponents.go
@@ -129,9 +129,9 @@ type attr struct {
 
 func (a *attr) Render() string {
 	if a.value == nil {
-		return fmt.Sprintf(" %v", a.name)
+		return " " + a.name
 	}
-	return fmt.Sprintf(` %v="%v"`, a.name, *a.value)
+	return " " + a.name + `="` + *a.value + `"`
 }
 
 func (a *attr) Place() Placement {
diff --git a/gomponents_test.go b/gomponents_test.go
index 33d32d1..2efdd7a 100644
--- a/gomponents_test.go
+++ b/gomponents_test.go
@@ -52,6 +52,22 @@ func TestAttr(t *testing.T) {
 	})
 }
 
+func BenchmarkAttr(b *testing.B) {
+	b.Run("boolean attributes", func(b *testing.B) {
+		for i := 0; i < b.N; i++ {
+			a := g.Attr("hat")
+			a.Render()
+		}
+	})
+
+	b.Run("name-value attributes", func(b *testing.B) {
+		for i := 0; i < b.N; i++ {
+			a := g.Attr("hat", "party")
+			a.Render()
+		}
+	})
+}
+
 type outsider struct{}
 
 func (o outsider) Render() string {
-- 
cgit 1.4.1