package scf_test import ( "encoding/json" "strconv" "strings" "testing" config "git.sharkk.net/Sharkk/Fin" "github.com/BurntSushi/toml" "gopkg.in/yaml.v3" ) func BenchmarkSmallConfig(b *testing.B) { // Small config with just a few key-value pairs smallConfig := ` host "localhost" port 8080 debug true timeout 30 ` b.ResetTimer() for i := 0; i < b.N; i++ { reader := strings.NewReader(smallConfig) _, err := config.Load(reader) if err != nil { b.Fatalf("Failed to parse small config: %v", err) } } } func BenchmarkMediumConfig(b *testing.B) { // Medium config with nested structures and arrays mediumConfig := ` app { name "TestApp" version "1.0.0" enableLogging true } database { host "db.example.com" port 5432 credentials { username "admin" password "secure123" } } features { "authentication" "authorization" "reporting" "analytics" } timeouts { connect 5 read 10 write 10 idle 60 } -- Comments to add some parsing overhead endpoints { api "/api/v1" web "/web" admin "/admin" health "/health" } ` b.ResetTimer() for i := 0; i < b.N; i++ { reader := strings.NewReader(mediumConfig) _, err := config.Load(reader) if err != nil { b.Fatalf("Failed to parse medium config: %v", err) } } } func BenchmarkLargeConfig(b *testing.B) { // Simpler large config with careful bracket matching largeConfig := ` application { name "EnterpriseApp" version "2.5.1" environment "production" debug false maxConnections 1000 timeout 30 retryCount 3 logLevel "info" } -- Database cluster configuration databases { primary { host "primary-db.example.com" port 5432 maxConnections 100 credentials { username "app_user" password "super_secret" ssl true timeout 5 } } replica { host "replica-db.example.com" port 5432 maxConnections 200 credentials { username "read_user" password "read_only_pw" ssl true } } } allowedIPs { "192.168.1.1" "192.168.1.2" "192.168.1.3" "192.168.1.4" "192.168.1.5" } -- Add 50 numbered settings to make the config large settings {` // Add many numbered settings var builder strings.Builder builder.WriteString(largeConfig) for i := 1; i <= 50; i++ { builder.WriteString("\n\t\tsetting") builder.WriteString(strconv.Itoa(i)) builder.WriteString(" ") builder.WriteString(strconv.Itoa(i * 10)) } // Close the settings block and add one more block builder.WriteString(` } roles { admin { permissions { "read" "write" "delete" "admin" } } user { permissions { "read" "write" } } } `) largeConfig = builder.String() b.ResetTimer() for i := 0; i < b.N; i++ { reader := strings.NewReader(largeConfig) _, err := config.Load(reader) if err != nil { b.Fatalf("Failed to parse large config: %v", err) } } } // JSON Benchmarks func BenchmarkSmallConfigJSON(b *testing.B) { smallConfigJSON := `{ "host": "localhost", "port": 8080, "debug": true, "timeout": 30 }` b.ResetTimer() for i := 0; i < b.N; i++ { reader := strings.NewReader(smallConfigJSON) var result map[string]interface{} decoder := json.NewDecoder(reader) err := decoder.Decode(&result) if err != nil { b.Fatalf("Failed to parse small JSON config: %v", err) } } } func BenchmarkMediumConfigJSON(b *testing.B) { mediumConfigJSON := `{ "app": { "name": "TestApp", "version": "1.0.0", "enableLogging": true }, "database": { "host": "db.example.com", "port": 5432, "credentials": { "username": "admin", "password": "secure123" } }, "features": [ "authentication", "authorization", "reporting", "analytics" ], "timeouts": { "connect": 5, "read": 10, "write": 10, "idle": 60 }, "endpoints": { "api": "/api/v1", "web": "/web", "admin": "/admin", "health": "/health" } }` b.ResetTimer() for i := 0; i < b.N; i++ { reader := strings.NewReader(mediumConfigJSON) var result map[string]interface{} decoder := json.NewDecoder(reader) err := decoder.Decode(&result) if err != nil { b.Fatalf("Failed to parse medium JSON config: %v", err) } } } func BenchmarkLargeConfigJSON(b *testing.B) { // Start building the large JSON config largeConfigJSON := `{ "application": { "name": "EnterpriseApp", "version": "2.5.1", "environment": "production", "debug": false, "maxConnections": 1000, "timeout": 30, "retryCount": 3, "logLevel": "info" }, "databases": { "primary": { "host": "primary-db.example.com", "port": 5432, "maxConnections": 100, "credentials": { "username": "app_user", "password": "super_secret", "ssl": true, "timeout": 5 } }, "replica": { "host": "replica-db.example.com", "port": 5432, "maxConnections": 200, "credentials": { "username": "read_user", "password": "read_only_pw", "ssl": true } } }, "allowedIPs": [ "192.168.1.1", "192.168.1.2", "192.168.1.3", "192.168.1.4", "192.168.1.5" ], "settings": {` var builder strings.Builder builder.WriteString(largeConfigJSON) // Add many numbered settings for i := 1; i <= 50; i++ { if i > 1 { builder.WriteString(",") } builder.WriteString("\n\t\t\t\"setting") builder.WriteString(strconv.Itoa(i)) builder.WriteString("\": ") builder.WriteString(strconv.Itoa(i * 10)) } // Close the settings block and add roles builder.WriteString(` }, "roles": { "admin": { "permissions": [ "read", "write", "delete", "admin" ] }, "user": { "permissions": [ "read", "write" ] } } }`) largeConfigJSONString := builder.String() b.ResetTimer() for i := 0; i < b.N; i++ { reader := strings.NewReader(largeConfigJSONString) var result map[string]interface{} decoder := json.NewDecoder(reader) err := decoder.Decode(&result) if err != nil { b.Fatalf("Failed to parse large JSON config: %v", err) } } } // YAML Benchmarks func BenchmarkSmallConfigYAML(b *testing.B) { smallConfigYAML := ` host: localhost port: 8080 debug: true timeout: 30 ` b.ResetTimer() for i := 0; i < b.N; i++ { var result map[string]interface{} err := yaml.Unmarshal([]byte(smallConfigYAML), &result) if err != nil { b.Fatalf("Failed to parse small YAML config: %v", err) } } } func BenchmarkMediumConfigYAML(b *testing.B) { mediumConfigYAML := ` app: name: TestApp version: 1.0.0 enableLogging: true database: host: db.example.com port: 5432 credentials: username: admin password: secure123 features: - authentication - authorization - reporting - analytics timeouts: connect: 5 read: 10 write: 10 idle: 60 # Comments to add some parsing overhead endpoints: api: /api/v1 web: /web admin: /admin health: /health ` b.ResetTimer() for i := 0; i < b.N; i++ { var result map[string]interface{} err := yaml.Unmarshal([]byte(mediumConfigYAML), &result) if err != nil { b.Fatalf("Failed to parse medium YAML config: %v", err) } } } func BenchmarkLargeConfigYAML(b *testing.B) { // Start building the large YAML config largeConfigYAML := ` application: name: EnterpriseApp version: 2.5.1 environment: production debug: false maxConnections: 1000 timeout: 30 retryCount: 3 logLevel: info # Database cluster configuration databases: primary: host: primary-db.example.com port: 5432 maxConnections: 100 credentials: username: app_user password: super_secret ssl: true timeout: 5 replica: host: replica-db.example.com port: 5432 maxConnections: 200 credentials: username: read_user password: read_only_pw ssl: true allowedIPs: - 192.168.1.1 - 192.168.1.2 - 192.168.1.3 - 192.168.1.4 - 192.168.1.5 # Add 50 numbered settings to make the config large settings: ` var builder strings.Builder builder.WriteString(largeConfigYAML) // Add many numbered settings for i := 1; i <= 50; i++ { builder.WriteString(" setting") builder.WriteString(strconv.Itoa(i)) builder.WriteString(": ") builder.WriteString(strconv.Itoa(i * 10)) builder.WriteString("\n") } // Add roles builder.WriteString(` roles: admin: permissions: - read - write - delete - admin user: permissions: - read - write `) largeConfigYAMLString := builder.String() b.ResetTimer() for i := 0; i < b.N; i++ { var result map[string]interface{} err := yaml.Unmarshal([]byte(largeConfigYAMLString), &result) if err != nil { b.Fatalf("Failed to parse large YAML config: %v", err) } } } // TOML Benchmarks func BenchmarkSmallConfigTOML(b *testing.B) { smallConfigTOML := ` host = "localhost" port = 8080 debug = true timeout = 30 ` b.ResetTimer() for i := 0; i < b.N; i++ { var result map[string]interface{} err := toml.Unmarshal([]byte(smallConfigTOML), &result) if err != nil { b.Fatalf("Failed to parse small TOML config: %v", err) } } } func BenchmarkMediumConfigTOML(b *testing.B) { mediumConfigTOML := ` [app] name = "TestApp" version = "1.0.0" enableLogging = true [database] host = "db.example.com" port = 5432 [database.credentials] username = "admin" password = "secure123" features = ["authentication", "authorization", "reporting", "analytics"] [timeouts] connect = 5 read = 10 write = 10 idle = 60 # Comments to add some parsing overhead [endpoints] api = "/api/v1" web = "/web" admin = "/admin" health = "/health" ` b.ResetTimer() for i := 0; i < b.N; i++ { var result map[string]interface{} err := toml.Unmarshal([]byte(mediumConfigTOML), &result) if err != nil { b.Fatalf("Failed to parse medium TOML config: %v", err) } } } func BenchmarkLargeConfigTOML(b *testing.B) { // Start building the large TOML config largeConfigTOML := ` [application] name = "EnterpriseApp" version = "2.5.1" environment = "production" debug = false maxConnections = 1000 timeout = 30 retryCount = 3 logLevel = "info" # Database cluster configuration [databases.primary] host = "primary-db.example.com" port = 5432 maxConnections = 100 [databases.primary.credentials] username = "app_user" password = "super_secret" ssl = true timeout = 5 [databases.replica] host = "replica-db.example.com" port = 5432 maxConnections = 200 [databases.replica.credentials] username = "read_user" password = "read_only_pw" ssl = true allowedIPs = ["192.168.1.1", "192.168.1.2", "192.168.1.3", "192.168.1.4", "192.168.1.5"] # Add 50 numbered settings to make the config large [settings] ` var builder strings.Builder builder.WriteString(largeConfigTOML) // Add many numbered settings for i := 1; i <= 50; i++ { builder.WriteString("setting") builder.WriteString(strconv.Itoa(i)) builder.WriteString(" = ") builder.WriteString(strconv.Itoa(i * 10)) builder.WriteString("\n") } // Add roles builder.WriteString(` [roles.admin] permissions = ["read", "write", "delete", "admin"] [roles.user] permissions = ["read", "write"] `) largeConfigTOMLString := builder.String() b.ResetTimer() for i := 0; i < b.N; i++ { var result map[string]interface{} err := toml.Unmarshal([]byte(largeConfigTOMLString), &result) if err != nil { b.Fatalf("Failed to parse large TOML config: %v", err) } } }