Skip to content

Commit f1ab145

Browse files
committed
add benchmark tests for all supported syntaxes with performance metrics in README and CHANGELOG updates
1 parent e8839ff commit f1ab145

3 files changed

Lines changed: 157 additions & 1 deletion

File tree

CHANGELOG.md

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,12 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
77

88
## [Unreleased]
99

10+
## [0.7.0] - 2026-05-07
11+
12+
### Added
13+
- Benchmark tests (`extract_bench_test.go`) for all 7 formats: OpenGraph, X Cards, JSON-LD, W3C Microdata, RDFa, Dublin Core, and Microformats, plus a combined all-syntaxes benchmark
14+
- Performance section in README with benchmark results table and instructions for running benchmarks
15+
1016
## [0.6.0] - 2026-05-06
1117

1218
### Added
@@ -131,7 +137,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
131137
- Support for providing raw HTML content directly (bypassing HTTP fetch)
132138
- Examples: simple extraction, OpenGraph-only, configuring specific syntaxes
133139

134-
[Unreleased]: https://github.com/aafeher/go-microdata-extract/compare/v0.6.0...HEAD
140+
[Unreleased]: https://github.com/aafeher/go-microdata-extract/compare/v0.7.0...HEAD
141+
[0.7.0]: https://github.com/aafeher/go-microdata-extract/compare/v0.6.0...v0.7.0
135142
[0.6.0]: https://github.com/aafeher/go-microdata-extract/compare/v0.5.0...v0.6.0
136143
[0.5.0]: https://github.com/aafeher/go-microdata-extract/compare/v0.4.0...v0.5.0
137144
[0.4.0]: https://github.com/aafeher/go-microdata-extract/compare/v0.3.0...v0.4.0

README.md

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -126,6 +126,27 @@ e, err := e.Extract("https://github.com/aafeher/go-microdata-extract", nil)
126126

127127
In this example, structured data is extracted from "https://github.com/aafeher/go-microdata-extract". The function fetches the content itself, as we passed nil as the urlContent.
128128

129+
## Performance
130+
131+
Benchmarks run on a 12th Gen Intel Core i7-1260P (16 threads), Go 1.25.0, measuring parse time per operation with content provided directly (no HTTP fetch overhead). Each extractor is run in isolation.
132+
133+
| Format | ns/op | B/op | allocs/op |
134+
|---------------|--------:|--------:|----------:|
135+
| OpenGraph | ~14,600 | 9,152 | 115 |
136+
| X Cards | ~22,000 | 16,232 | 163 |
137+
| JSON-LD | ~22,100 | 12,272 | 115 |
138+
| W3C Microdata | ~19,200 | 14,916 | 170 |
139+
| RDFa | ~14,300 | 12,408 | 132 |
140+
| Dublin Core | ~10,900 | 9,184 | 87 |
141+
| Microformats | ~17,900 | 12,760 | 149 |
142+
| All 7 (concurrent) | ~108,000 | 112,788 | 1,073 |
143+
144+
Run benchmarks with:
145+
146+
```bash
147+
go test -bench=. -benchmem ./...
148+
```
149+
129150
## Examples
130151

131152
Examples can be found in [/examples](https://github.com/aafeher/go-microdata-extract/tree/main/examples).

extract_bench_test.go

Lines changed: 128 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,128 @@
1+
package extract
2+
3+
import (
4+
"os"
5+
"testing"
6+
)
7+
8+
const benchAllSyntaxesHTML = `<!DOCTYPE html>
9+
<html lang="en">
10+
<head>
11+
<meta charset="UTF-8">
12+
<title>Combined all formats benchmark</title>
13+
<meta property="og:title" content="OpenGraph Article Title"/>
14+
<meta property="og:type" content="article"/>
15+
<meta property="og:url" content="https://www.example.com/article"/>
16+
<meta name="twitter:card" content="summary_large_image"/>
17+
<meta name="twitter:title" content="X Cards Article Title"/>
18+
<meta name="DC.title" content="Dublin Core Title"/>
19+
<meta name="DC.creator" content="Jane Doe"/>
20+
<meta name="DC.subject" content="Technology"/>
21+
<script type="application/ld+json">
22+
{"@context":"https://schema.org/","@type":"Article","name":"JSON-LD Article","author":{"@type":"Person","name":"John Doe"}}
23+
</script>
24+
</head>
25+
<body>
26+
<div itemscope itemtype="https://schema.org/Person">
27+
<span itemprop="name">John Doe</span>
28+
<span itemprop="jobTitle">Engineer</span>
29+
</div>
30+
<div vocab="https://schema.org/" typeof="Person">
31+
<span property="name">Jane Doe</span>
32+
<span property="jobTitle">Designer</span>
33+
</div>
34+
<div class="h-card">
35+
<span class="p-name">Test Person</span>
36+
<a class="u-url" href="https://example.com">example.com</a>
37+
</div>
38+
</body>
39+
</html>`
40+
41+
func readBenchFixture(b *testing.B, path string) string {
42+
b.Helper()
43+
data, err := os.ReadFile(path)
44+
if err != nil {
45+
b.Fatalf("failed to read fixture %s: %v", path, err)
46+
}
47+
return string(data)
48+
}
49+
50+
func BenchmarkExtract_OpenGraph(b *testing.B) {
51+
content := readBenchFixture(b, "test/test-11-opengraph-article.html")
52+
b.ReportAllocs()
53+
b.ResetTimer()
54+
for i := 0; i < b.N; i++ {
55+
e := New().SetSyntaxes([]Syntax{SyntaxOpenGraph})
56+
_, _ = e.Extract("http://example.com", &content)
57+
}
58+
}
59+
60+
func BenchmarkExtract_XCards(b *testing.B) {
61+
content := readBenchFixture(b, "test/test-25-xcards-article.html")
62+
b.ReportAllocs()
63+
b.ResetTimer()
64+
for i := 0; i < b.N; i++ {
65+
e := New().SetSyntaxes([]Syntax{SyntaxXCards})
66+
_, _ = e.Extract("http://example.com", &content)
67+
}
68+
}
69+
70+
func BenchmarkExtract_JSONLD(b *testing.B) {
71+
content := readBenchFixture(b, "test/test-31-ldjson-multiple-objects.html")
72+
b.ReportAllocs()
73+
b.ResetTimer()
74+
for i := 0; i < b.N; i++ {
75+
e := New().SetSyntaxes([]Syntax{SyntaxJSONLD})
76+
_, _ = e.Extract("http://example.com", &content)
77+
}
78+
}
79+
80+
func BenchmarkExtract_Microdata(b *testing.B) {
81+
content := readBenchFixture(b, "test/test-34-w3cmicrodata-extended.html")
82+
b.ReportAllocs()
83+
b.ResetTimer()
84+
for i := 0; i < b.N; i++ {
85+
e := New().SetSyntaxes([]Syntax{SyntaxMicrodata})
86+
_, _ = e.Extract("http://example.com", &content)
87+
}
88+
}
89+
90+
func BenchmarkExtract_RDFa(b *testing.B) {
91+
content := readBenchFixture(b, "test/test-42-rdfa-multiple.html")
92+
b.ReportAllocs()
93+
b.ResetTimer()
94+
for i := 0; i < b.N; i++ {
95+
e := New().SetSyntaxes([]Syntax{SyntaxRDFa})
96+
_, _ = e.Extract("http://example.com", &content)
97+
}
98+
}
99+
100+
func BenchmarkExtract_DublinCore(b *testing.B) {
101+
content := readBenchFixture(b, "test/test-47-dublincore-multiple.html")
102+
b.ReportAllocs()
103+
b.ResetTimer()
104+
for i := 0; i < b.N; i++ {
105+
e := New().SetSyntaxes([]Syntax{SyntaxDublinCore})
106+
_, _ = e.Extract("http://example.com", &content)
107+
}
108+
}
109+
110+
func BenchmarkExtract_Microformats(b *testing.B) {
111+
content := readBenchFixture(b, "test/test-53-microformats-extended.html")
112+
b.ReportAllocs()
113+
b.ResetTimer()
114+
for i := 0; i < b.N; i++ {
115+
e := New().SetSyntaxes([]Syntax{SyntaxMicroformats})
116+
_, _ = e.Extract("http://example.com", &content)
117+
}
118+
}
119+
120+
func BenchmarkExtract_AllSyntaxes(b *testing.B) {
121+
content := benchAllSyntaxesHTML
122+
b.ReportAllocs()
123+
b.ResetTimer()
124+
for i := 0; i < b.N; i++ {
125+
e := New()
126+
_, _ = e.Extract("http://example.com", &content)
127+
}
128+
}

0 commit comments

Comments
 (0)