Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions benchmarks/Dockerfile.tinygo
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
ARG TINYGO_VERSION=0.40.0
FROM tinygo/tinygo:${TINYGO_VERSION}
WORKDIR /home/tinygo
ADD --chown=tinygo:tinygo go-benchmark go-benchmark
WORKDIR /home/tinygo/go-benchmark
RUN tinygo build -o benchmark.wasm -target=wasi .
USER root
RUN mkdir -p /benchmark && cp benchmark.wasm /benchmark/
# We output the Wasm file to the `/benchmark` directory, where the client expects it.
2 changes: 2 additions & 0 deletions benchmarks/all.suite
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,8 @@ shootout/shootout-sieve.wasm
shootout/shootout-switch.wasm
shootout/shootout-xblabla20.wasm
shootout/shootout-xchacha20.wasm
tinygo/tinygo-json.wasm
tinygo/tinygo-regex.wasm
spidermonkey/benchmark.wasm
tract-onnx-image-classification/benchmark.wasm
richards/benchmark.wasm
Expand Down
7 changes: 7 additions & 0 deletions benchmarks/tinygo.suite
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
# TinyGo benchmarks - benchmarks compiled with TinyGo to WebAssembly.
#
# TinyGo is a Go compiler designed for small places, producing compact
# WebAssembly binaries suitable for resource-constrained environments.

tinygo/tinygo-json.wasm
tinygo/tinygo-regex.wasm
19 changes: 19 additions & 0 deletions benchmarks/tinygo/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
ARG TINYGO_VERSION=0.40.0
FROM tinygo/tinygo:${TINYGO_VERSION}

WORKDIR /usr/src

# Copy all benchmark source and build script
COPY --chown=tinygo:tinygo json json
COPY --chown=tinygo:tinygo regex regex
COPY --chown=tinygo:tinygo build.sh .

# Create output directory as root and set permissions
USER root
RUN mkdir -p /benchmark && chown tinygo:tinygo /benchmark

# Switch back to tinygo user and build
USER tinygo
RUN OUTPUT_DIR=/benchmark ./build.sh

# Output goes to /benchmark where sightglass expects it
32 changes: 32 additions & 0 deletions benchmarks/tinygo/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
# TinyGo Benchmarks

This directory contains multiple benchmarks compiled with TinyGo to WebAssembly.

TinyGo is a Go compiler designed for small places, producing compact
WebAssembly binaries suitable for resource-constrained environments.

## Benchmarks

### tinygo-json.wasm
JSON serialization and deserialization using Go's `encoding/json` package.
- Input: ~2.1MB JSON file with 100 user records
- Tests: Parse and stringify operations

### tinygo-regex.wasm
Regular expression matching using Go's `regexp` package.
- Input: ~6.5MB text corpus (same as `benchmarks/regex/default.input`)
- Tests: 3 regex patterns (emails, URIs, IPs) matching the Rust benchmark

## Building

From the `benchmarks` directory:

```bash
./build.sh tinygo/
```

## Adding New Benchmarks

To add a new TinyGo benchmark, create a new directory containing `main.go`,
`go.mod`, `default.input`, and expected output files. The build script will
automatically discover and build it.
34 changes: 34 additions & 0 deletions benchmarks/tinygo/build.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
#!/bin/sh
set -e

# Configuration
TINYGO="${TINYGO:-tinygo}"
OUTPUT_DIR="${OUTPUT_DIR:-$(pwd)}"
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"

# Create output directory if it doesn't exist
mkdir -p "$OUTPUT_DIR"

cd "$SCRIPT_DIR"

# Auto-discover benchmarks: any directory with a main.go
for dir in */; do
# Remove trailing slash
benchmark=$(basename "$dir")

# Skip if not a benchmark directory (no main.go)
[ ! -f "$dir/main.go" ] && continue

echo "Building TinyGo $benchmark benchmark..."

cd "$dir"

# Build with TinyGo
"$TINYGO" build -o "$OUTPUT_DIR/tinygo-$benchmark.wasm" -target=wasi -opt=2 -gc=leaking .

cd "$SCRIPT_DIR"

echo "> Built tinygo-$benchmark.wasm"
done

echo "All TinyGo benchmarks built successfully"
3 changes: 3 additions & 0 deletions benchmarks/tinygo/json/go.mod
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
module benchmark

go 1.21
92 changes: 92 additions & 0 deletions benchmarks/tinygo/json/main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
// TinyGo JSON serialization and deserialization benchmark.
//
// This benchmark tests JSON parsing and serialization performance using
// the standard library encoding/json package.

package main

import (
"encoding/json"
"fmt"
"os"
)

// WASM imports for sightglass API
//
//go:wasm-module bench
//export start
func benchStart()

//go:wasm-module bench
//export end
func benchEnd()

// Data structures matching the Rust benchmark
type User struct {
ID uint64 `json:"id"`
Username string `json:"username"`
Email string `json:"email"`
FullName string `json:"full_name"`
IsActive bool `json:"is_active"`
CreatedAt string `json:"created_at"`
UpdatedAt string `json:"updated_at"`
Profile Profile `json:"profile"`
Settings Settings `json:"settings"`
Posts []Post `json:"posts"`
}

type Profile struct {
Bio string `json:"bio"`
AvatarURL string `json:"avatar_url"`
Location string `json:"location"`
Website *string `json:"website"`
SocialLinks []string `json:"social_links"`
}

type Settings struct {
Theme string `json:"theme"`
Language string `json:"language"`
NotificationsEnabled bool `json:"notifications_enabled"`
PrivacyLevel string `json:"privacy_level"`
Preferences map[string]string `json:"preferences"`
}

type Post struct {
ID uint64 `json:"id"`
Title string `json:"title"`
Content string `json:"content"`
Tags []string `json:"tags"`
Likes uint32 `json:"likes"`
CommentsCount uint32 `json:"comments_count"`
PublishedAt string `json:"published_at"`
}

func main() {
// Read the JSON input file
jsonData, err := os.ReadFile("tinygo-json.input")
if err != nil {
fmt.Fprintf(os.Stderr, "Error reading input: %v\n", err)
os.Exit(1)
}

benchStart()

// Deserialize: Parse JSON into structured data
var users []User
if err := json.Unmarshal(jsonData, &users); err != nil {
fmt.Fprintf(os.Stderr, "Error parsing JSON: %v\n", err)
os.Exit(1)
}

// Serialize: Convert back to JSON
serialized, err := json.Marshal(users)
if err != nil {
fmt.Fprintf(os.Stderr, "Error serializing JSON: %v\n", err)
os.Exit(1)
}

benchEnd()

fmt.Fprintf(os.Stderr, "[tinygo-json] processed %d users\n", len(users))
fmt.Fprintf(os.Stderr, "[tinygo-json] serialized size: %d bytes\n", len(serialized))
}
3 changes: 3 additions & 0 deletions benchmarks/tinygo/regex/go.mod
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
module tinygo-regex

go 1.21
56 changes: 56 additions & 0 deletions benchmarks/tinygo/regex/main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
// TinyGo regex benchmark.
//
// This benchmark tests regular expression matching performance using
// the standard library regexp package.

package main

import (
"fmt"
"os"
"regexp"
)

// WASM imports for sightglass API
//
//go:wasm-module bench
//export start
func benchStart()

//go:wasm-module bench
//export end
func benchEnd()

func main() {
// Read the input text file
path := "tinygo-regex.input"
fmt.Fprintf(os.Stderr, "[regex] matching %s\n", path)
data, err := os.ReadFile(path)
if err != nil {
fmt.Fprintf(os.Stderr, "Error reading input: %v\n", err)
os.Exit(1)
}
text := string(data)

// Use the same patterns as the Rust benchmark
emailPattern := `[\w\.+-]+@[\w\.-]+\.[\w\.-]+`
uriPattern := `[\w]+://[^/\s?#]+[^\s?#]+(?:\?[^\s#]*)?(?:#[^\s]*)?`
ipPattern := `(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9])\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9])`

benchStart()

emails := countMatches(text, emailPattern)
uris := countMatches(text, uriPattern)
ips := countMatches(text, ipPattern)

benchEnd()

fmt.Fprintf(os.Stderr, "[regex] found %d emails\n", emails)
fmt.Fprintf(os.Stderr, "[regex] found %d URIs\n", uris)
fmt.Fprintf(os.Stderr, "[regex] found %d IPs\n", ips)
}

func countMatches(text, pattern string) int {
re := regexp.MustCompile(pattern)
return len(re.FindAllString(text, -1))
}
Loading