ref 9
This commit is contained in:
parent
456854246b
commit
b334b09efa
|
@ -2,7 +2,6 @@ package config
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"strconv"
|
|
||||||
"strings"
|
"strings"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
|
@ -11,612 +10,6 @@ import (
|
||||||
"gopkg.in/yaml.v3"
|
"gopkg.in/yaml.v3"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Original benchmarks
|
|
||||||
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)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Value Retrieval Benchmarks for Custom Config Format
|
|
||||||
func BenchmarkRetrieveSimpleValues(b *testing.B) {
|
func BenchmarkRetrieveSimpleValues(b *testing.B) {
|
||||||
configData := `
|
configData := `
|
||||||
host "localhost"
|
host "localhost"
|
617
bench/parse_test.go
Normal file
617
bench/parse_test.go
Normal file
|
@ -0,0 +1,617 @@
|
||||||
|
package config
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/json"
|
||||||
|
"strconv"
|
||||||
|
"strings"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
config "git.sharkk.net/Go/Config"
|
||||||
|
"github.com/BurntSushi/toml"
|
||||||
|
"gopkg.in/yaml.v3"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Original benchmarks
|
||||||
|
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)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
12
pool.go
12
pool.go
|
@ -6,8 +6,8 @@ import (
|
||||||
|
|
||||||
// byteSlicePool helps reuse byte slices
|
// byteSlicePool helps reuse byte slices
|
||||||
var byteSlicePool = sync.Pool{
|
var byteSlicePool = sync.Pool{
|
||||||
New: func() interface{} {
|
New: func() any {
|
||||||
b := make([]byte, 0, 128)
|
b := make([]byte, 0, 64)
|
||||||
return &b
|
return &b
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
@ -27,8 +27,8 @@ func PutByteSlice(b *[]byte) {
|
||||||
|
|
||||||
// mapPool helps reuse maps for config objects
|
// mapPool helps reuse maps for config objects
|
||||||
var mapPool = sync.Pool{
|
var mapPool = sync.Pool{
|
||||||
New: func() interface{} {
|
New: func() any {
|
||||||
m := make(map[string]any, 16)
|
m := make(map[string]any, 8)
|
||||||
return &m
|
return &m
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
@ -51,8 +51,8 @@ func PutMap(m *map[string]any) {
|
||||||
|
|
||||||
// arrayPool helps reuse slices
|
// arrayPool helps reuse slices
|
||||||
var arrayPool = sync.Pool{
|
var arrayPool = sync.Pool{
|
||||||
New: func() interface{} {
|
New: func() any {
|
||||||
a := make([]any, 0, 8)
|
a := make([]any, 0, 4)
|
||||||
return &a
|
return &a
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
|
@ -29,7 +29,7 @@ type Scanner struct {
|
||||||
|
|
||||||
// scannerPool helps reuse scanner objects
|
// scannerPool helps reuse scanner objects
|
||||||
var scannerPool = sync.Pool{
|
var scannerPool = sync.Pool{
|
||||||
New: func() interface{} {
|
New: func() any {
|
||||||
bufferRef := GetByteSlice()
|
bufferRef := GetByteSlice()
|
||||||
return &Scanner{
|
return &Scanner{
|
||||||
line: 1,
|
line: 1,
|
||||||
|
@ -43,7 +43,7 @@ var scannerPool = sync.Pool{
|
||||||
// NewScanner creates a new scanner from a pool
|
// NewScanner creates a new scanner from a pool
|
||||||
func NewScanner(r io.Reader) *Scanner {
|
func NewScanner(r io.Reader) *Scanner {
|
||||||
s := scannerPool.Get().(*Scanner)
|
s := scannerPool.Get().(*Scanner)
|
||||||
s.reader = bufio.NewReader(r)
|
s.reader = bufio.NewReaderSize(r, 1024)
|
||||||
s.line = 1
|
s.line = 1
|
||||||
s.col = 0
|
s.col = 0
|
||||||
s.buffer = (*s.bufferRef)[:0]
|
s.buffer = (*s.bufferRef)[:0]
|
||||||
|
|
Loading…
Reference in New Issue
Block a user