stardb/testing/perf_test.go

129 lines
2.8 KiB
Go

package testing
import (
"fmt"
"testing"
"time"
"b612.me/stardb"
_ "modernc.org/sqlite"
)
func setupBenchmarkDB(b *testing.B) *stardb.StarDB {
b.Helper()
db := &stardb.StarDB{}
if err := db.Open("sqlite", ":memory:"); err != nil {
b.Fatalf("Failed to open database: %v", err)
}
_, err := db.Exec(`
CREATE TABLE users (
id INTEGER PRIMARY KEY AUTOINCREMENT,
name TEXT NOT NULL,
email TEXT NOT NULL,
age INTEGER,
balance REAL,
active BOOLEAN,
created_at DATETIME
)
`)
if err != nil {
b.Fatalf("Failed to create table: %v", err)
}
_, err = db.Exec(`
INSERT INTO users (name, email, age, balance, active, created_at) VALUES
('Alice', 'alice@example.com', 25, 100.50, 1, '2024-01-01 10:00:00'),
('Bob', 'bob@example.com', 30, 200.75, 1, '2024-01-02 11:00:00'),
('Charlie', 'charlie@example.com', 35, 300.25, 0, '2024-01-03 12:00:00')
`)
if err != nil {
b.Fatalf("Failed to insert seed data: %v", err)
}
return db
}
func BenchmarkQueryX(b *testing.B) {
db := setupBenchmarkDB(b)
defer db.Close()
target := User{Name: "Alice"}
b.ReportAllocs()
b.ResetTimer()
for i := 0; i < b.N; i++ {
rows, err := db.QueryX(&target, "SELECT * FROM users WHERE name = ?", ":name")
if err != nil {
b.Fatalf("QueryX failed: %v", err)
}
_ = rows.Close()
}
}
func BenchmarkOrm(b *testing.B) {
db := setupBenchmarkDB(b)
defer db.Close()
b.ReportAllocs()
b.ResetTimer()
for i := 0; i < b.N; i++ {
rows, err := db.Query("SELECT * FROM users ORDER BY name")
if err != nil {
b.Fatalf("Query failed: %v", err)
}
var users []User
if err := rows.Orm(&users); err != nil {
_ = rows.Close()
b.Fatalf("Orm failed: %v", err)
}
_ = rows.Close()
}
}
func BenchmarkScanEach(b *testing.B) {
db := setupBenchmarkDB(b)
defer db.Close()
b.ReportAllocs()
b.ResetTimer()
for i := 0; i < b.N; i++ {
count := 0
err := db.ScanEach("SELECT * FROM users ORDER BY name", func(row *stardb.StarResult) error {
_ = row.MustString("name")
count++
return nil
})
if err != nil {
b.Fatalf("ScanEach failed: %v", err)
}
if count != 3 {
b.Fatalf("Unexpected row count: %d", count)
}
}
}
func BenchmarkBatchInsert(b *testing.B) {
db := setupBenchmarkDB(b)
defer db.Close()
columns := []string{"name", "email", "age", "balance", "active", "created_at"}
b.ReportAllocs()
b.ResetTimer()
for i := 0; i < b.N; i++ {
base := i * 2
values := [][]interface{}{
{fmt.Sprintf("bench_user_%d", base), fmt.Sprintf("bench_%d@example.com", base), 20 + (base % 20), 99.5, true, time.Now()},
{fmt.Sprintf("bench_user_%d", base+1), fmt.Sprintf("bench_%d@example.com", base+1), 20 + ((base + 1) % 20), 199.5, false, time.Now()},
}
if _, err := db.BatchInsert("users", columns, values); err != nil {
b.Fatalf("BatchInsert failed: %v", err)
}
}
}