diff --git a/db-esdk-performance-testing/benchmarks/config/test-scenarios.yaml b/db-esdk-performance-testing/benchmarks/config/test-scenarios.yaml new file mode 100644 index 000000000..36fe86e09 --- /dev/null +++ b/db-esdk-performance-testing/benchmarks/config/test-scenarios.yaml @@ -0,0 +1,54 @@ +# DB-ESDK Performance Test Scenarios Configuration + +# Data sizes to test (in bytes) +# Categories are for organization only - code processes all sizes regardless of category +data_sizes: + small: + - 1024 # 1KB + - 5120 # 5KB + - 10240 # 10KB + medium: + - 102400 # 100KB + - 512000 # 500KB + - 1048576 # 1MB + - 10000000 + large: + - 10485760 # 10MB + - 52428800 # 50MB + - 104857600 + - 100000000 # 100MB + +# Quick test configuration (reduced test set for faster execution) +quick_config: + data_sizes: + small: + - 102400 # 100KB - within DynamoDB's 400KB limit + iterations: + warmup: 3 # Reduced warmup iterations + measurement: 3 # Reduced measurement iterations + concurrency_levels: + - 1 + - 2 + test_types: + - "throughput" + - "memory" + - "concurrency" + +# Test iterations for statistical significance +iterations: + warmup: 5 # Warmup iterations (not counted) + measurement: 10 # Measurement iterations + +# Concurrency levels to test +concurrency_levels: + # - 1 + # - 2 + # - 4 + # - 8 + # - 16 + +# DynamoDB table name +table_name: "dbesdk-performance-testing" + +# Keyring +keyring: "raw-aes" \ No newline at end of file diff --git a/db-esdk-performance-testing/benchmarks/go/README.md b/db-esdk-performance-testing/benchmarks/go/README.md new file mode 100644 index 000000000..0d69f41d8 --- /dev/null +++ b/db-esdk-performance-testing/benchmarks/go/README.md @@ -0,0 +1,45 @@ +# ESDK Go Benchmark + +Performance benchmark suite for the AWS Encryption SDK (ESDK) Go implementation. + +## Quick Start + +```bash +# Run quick benchmark +go run . --config ../../config/test-scenarios.yaml --quick + +# Run full benchmark +go run . --config ../../config/test-scenarios.yaml +``` + +## Build + +```bash +# Build release binary +go build -o esdk-benchmark . + +# Run built binary +./esdk-benchmark --quick +``` + +## Configuration + +The benchmark uses YAML configuration files. See `../../config/test-scenarios.yaml` for the full configuration format. + +### Quick Mode + +Quick mode runs a subset of tests with reduced iterations: + +- Only runs test types specified in `quick_config.test_types` +- Uses smaller data sizes from `quick_config.data_sizes.small` +- Fewer iterations: `quick_config.iterations.measurement` + +## Test Types + +- **throughput**: Measures operations per second and latency +- **memory**: Measures peak memory usage during operations +- **concurrency**: Tests performance under concurrent load + +## Output + +Results are saved to JSON format in `../../results/raw-data/go_results.json` by default. diff --git a/db-esdk-performance-testing/benchmarks/go/benchmark/benchmark_tests.go b/db-esdk-performance-testing/benchmarks/go/benchmark/benchmark_tests.go new file mode 100644 index 000000000..39f51f3ec --- /dev/null +++ b/db-esdk-performance-testing/benchmarks/go/benchmark/benchmark_tests.go @@ -0,0 +1,110 @@ +// Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. +// SPDX-License-Identifier: Apache-2.0 + +package benchmark + +import ( + "context" + "fmt" + "reflect" + "runtime/metrics" + "time" + + dbesdkitemencryptortypes "github.com/aws/aws-database-encryption-sdk-dynamodb/releases/go/dynamodb-esdk/awscryptographydbencryptionsdkdynamodbitemencryptorsmithygeneratedtypes" + "github.com/aws/aws-sdk-go-v2/service/dynamodb/types" +) + +// === Helper Functions === + +// runItemEncryptorCycle performs a item encryptor encrypt and decrypt cycle with 25 items and measures performance +func (b *DBESDKBenchmark) runItemEncryptorCycle(data []byte) (float64, float64, error) { + item := map[string]types.AttributeValue{ + "partition_key": &types.AttributeValueMemberS{Value: "benchmark-test"}, + "sort_key": &types.AttributeValueMemberN{Value: "0"}, + "attribute1": &types.AttributeValueMemberM{Value: map[string]types.AttributeValue{ + "data": &types.AttributeValueMemberB{Value: data}, + }}, + "attribute2": &types.AttributeValueMemberS{Value: "sign me!"}, + ":attribute3": &types.AttributeValueMemberS{Value: "ignore me!"}, + } + + encryptItemInput := &dbesdkitemencryptortypes.EncryptItemInput{ + PlaintextItem: item, + } + + encryptItemStart := time.Now() + encryptItemOutput, err := b.ItemEncryptorClient.EncryptItem(context.Background(), *encryptItemInput) + if err != nil { + return 0, 0, fmt.Errorf("EncryptItem failed: %w", err) + } + encryptItemDuration := time.Since(encryptItemStart).Seconds() * 1000 + // Demonstrate that the item has been encrypted + encryptedItem := encryptItemOutput.EncryptedItem + + // Directly decrypt the encrypted item using the DynamoDb Item Encryptor + decryptItemInput := &dbesdkitemencryptortypes.DecryptItemInput{ + EncryptedItem: encryptedItem, + } + decryptItemStart := time.Now() + decryptedItem, err := b.ItemEncryptorClient.DecryptItem(context.Background(), *decryptItemInput) + if err != nil { + return 0, 0, fmt.Errorf("EncryptItem failed: %w", err) + } + decryptItemDuration := time.Since(decryptItemStart).Seconds() * 1000 + + if !reflect.DeepEqual(item, decryptedItem.PlaintextItem) { + panic("Decrypted item does not match original item") + } + return encryptItemDuration, decryptItemDuration, nil +} + +// shouldRunTestType checks if a test type should be run based on quick config +func (b *DBESDKBenchmark) shouldRunTestType(testType string) bool { + if b.Config.QuickConfig == nil || len(b.Config.QuickConfig.TestTypes) == 0 { + return true + } + + for _, allowedType := range b.Config.QuickConfig.TestTypes { + if allowedType == testType { + return true + } + } + return false +} + +// === Memory Test Implementation === + +// sampleMemoryContinuously runs continuous memory sampling during operation +func (b *DBESDKBenchmark) sampleMemoryContinuously(beforeHeap, beforeAllocs uint64, stopChan chan bool) []MemorySample { + var samples []MemorySample + ticker := time.NewTicker(SamplingIntervalMs * time.Millisecond) + defer ticker.Stop() + + for { + select { + case <-stopChan: + return samples + case <-ticker.C: + var currentSamples [2]metrics.Sample + currentSamples[0].Name = "/memory/classes/heap/objects:bytes" + currentSamples[1].Name = "/gc/heap/allocs:bytes" + metrics.Read(currentSamples[:]) + + var heapDelta, allocsDelta uint64 + if currentSamples[0].Value.Uint64() > beforeHeap { + heapDelta = currentSamples[0].Value.Uint64() - beforeHeap + } + if currentSamples[1].Value.Uint64() > beforeAllocs { + allocsDelta = currentSamples[1].Value.Uint64() - beforeAllocs + } + + sample := MemorySample{ + Timestamp: time.Now(), + HeapMB: float64(heapDelta) / (1024 * 1024), + MetricsAllocsMB: float64(allocsDelta) / (1024 * 1024), + MemStatsAllocsMB: 0, + } + samples = append(samples, sample) + } + } +} diff --git a/db-esdk-performance-testing/benchmarks/go/benchmark/config.go b/db-esdk-performance-testing/benchmarks/go/benchmark/config.go new file mode 100644 index 000000000..2d50b3164 --- /dev/null +++ b/db-esdk-performance-testing/benchmarks/go/benchmark/config.go @@ -0,0 +1,67 @@ +// Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. +// SPDX-License-Identifier: Apache-2.0 + +package benchmark + +import ( + "fmt" + "os" + + "gopkg.in/yaml.v3" +) + +type KeyringType string + +const ( + RawAESKeying KeyringType = "raw-aes" +) + +// TestConfig represents the configuration for benchmark tests +type TestConfig struct { + DataSizes struct { + Small []int `yaml:"small"` + Medium []int `yaml:"medium"` + Large []int `yaml:"large"` + } `yaml:"data_sizes"` + Iterations struct { + Warmup int `yaml:"warmup"` + Measurement int `yaml:"measurement"` + } `yaml:"iterations"` + ConcurrencyLevels []int `yaml:"concurrency_levels"` + QuickConfig *QuickConfig `yaml:"quick_config"` + TableName string `yaml:"table_name"` + Keyring KeyringType `yaml:"keyring"` +} + +// QuickConfig represents the quick test configuration +type QuickConfig struct { + DataSizes struct { + Small []int `yaml:"small"` + } `yaml:"data_sizes"` + Iterations struct { + Warmup int `yaml:"warmup"` + Measurement int `yaml:"measurement"` + } `yaml:"iterations"` + ConcurrencyLevels []int `yaml:"concurrency_levels"` + TestTypes []string `yaml:"test_types"` +} + +// LoadConfig loads the test configuration from YAML file +func LoadConfig(configPath string) (TestConfig, error) { + var config TestConfig + + if _, err := os.Stat(configPath); os.IsNotExist(err) { + return config, fmt.Errorf("config file not found: %s", configPath) + } + + data, err := os.ReadFile(configPath) + if err != nil { + return config, fmt.Errorf("failed to read config file: %w", err) + } + + if err := yaml.Unmarshal(data, &config); err != nil { + return config, fmt.Errorf("failed to parse config file: %w", err) + } + + return config, nil +} diff --git a/db-esdk-performance-testing/benchmarks/go/benchmark/dbesdk_benchmark.go b/db-esdk-performance-testing/benchmarks/go/benchmark/dbesdk_benchmark.go new file mode 100644 index 000000000..62b5da17d --- /dev/null +++ b/db-esdk-performance-testing/benchmarks/go/benchmark/dbesdk_benchmark.go @@ -0,0 +1,199 @@ +// Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. +// SPDX-License-Identifier: Apache-2.0 + +package benchmark + +import ( + "context" + "crypto/rand" + "fmt" + "log" + "net/url" + "runtime" + + mplsmithygenerated "github.com/aws/aws-cryptographic-material-providers-library/releases/go/mpl/awscryptographymaterialproviderssmithygenerated" + mpltypes "github.com/aws/aws-cryptographic-material-providers-library/releases/go/mpl/awscryptographymaterialproviderssmithygeneratedtypes" + itemencryptor "github.com/aws/aws-database-encryption-sdk-dynamodb/releases/go/dynamodb-esdk/awscryptographydbencryptionsdkdynamodbitemencryptorsmithygenerated" + dbesdkitemencryptortypes "github.com/aws/aws-database-encryption-sdk-dynamodb/releases/go/dynamodb-esdk/awscryptographydbencryptionsdkdynamodbitemencryptorsmithygeneratedtypes" + dbesdkdynamodbencryptiontypes "github.com/aws/aws-database-encryption-sdk-dynamodb/releases/go/dynamodb-esdk/awscryptographydbencryptionsdkdynamodbsmithygeneratedtypes" + dbesdkstructuredencryptiontypes "github.com/aws/aws-database-encryption-sdk-dynamodb/releases/go/dynamodb-esdk/awscryptographydbencryptionsdkstructuredencryptionsmithygeneratedtypes" + "github.com/aws/aws-database-encryption-sdk-dynamodb/releases/go/dynamodb-esdk/dbesdkmiddleware" + "github.com/aws/aws-sdk-go-v2/config" + "github.com/aws/aws-sdk-go-v2/service/dynamodb" + smithyendpoints "github.com/aws/smithy-go/endpoints" + "github.com/shirou/gopsutil/v3/mem" +) + +// Constants for memory testing +const ( + MemoryTestIterations = 5 + SamplingIntervalMs = 1 + GCSettleTimeMs = 5 + FinalSampleWaitMs = 2 +) + +// DBESDKBenchmark is the main benchmark struct +type DBESDKBenchmark struct { + Config TestConfig + DbesdkClient *dynamodb.Client + ItemEncryptorClient *itemencryptor.Client + Keyring mpltypes.IKeyring + Results []BenchmarkResult + CPUCount int + TotalMemoryGB float64 +} + +// New creates a new benchmark instance +func New(configPath string) (*DBESDKBenchmark, error) { + benchmark := &DBESDKBenchmark{ + CPUCount: runtime.NumCPU(), + } + + // Get system memory + if vmStat, err := mem.VirtualMemory(); err == nil { + benchmark.TotalMemoryGB = float64(vmStat.Total) / (1024 * 1024 * 1024) + } + + // Load configuration + config, err := LoadConfig(configPath) + if err != nil { + return nil, fmt.Errorf("failed to load config: %w", err) + } + benchmark.Config = config + + // Setup MPL + if err := benchmark.setupMPL(); err != nil { + return nil, fmt.Errorf("failed to setup MPL: %w", err) + } + + // Setup DB-ESDK + if err := benchmark.setupDBESDK(false); err != nil { + return nil, fmt.Errorf("failed to setup DB-ESDK: %w", err) + } + + log.Printf("Initialized DB-ESDK Benchmark - CPU cores: %d, Memory: %.1fGB", + benchmark.CPUCount, benchmark.TotalMemoryGB) + + return benchmark, nil +} + +func (b *DBESDKBenchmark) setupMPL() error { + // Initialize the material providers client + matProvConfig := mpltypes.MaterialProvidersConfig{} + matProv, err := mplsmithygenerated.NewClient(matProvConfig) + if err != nil { + return fmt.Errorf("failed to create material providers client: %w", err) + } + + switch b.Config.Keyring { + case RawAESKeying: + b.Keyring, err = SetupRawAESKeyring(matProv) + if err != nil { + return fmt.Errorf("failed to create keyring: %w", err) + } + default: + return fmt.Errorf("unsupported keyring type: %s", b.Config.Keyring) + } + return nil +} + +// setupDBESDK initializes the DynamoDB client with DB-ESDK middleware and creates a default keyring which is AES keyring +func (b *DBESDKBenchmark) setupDBESDK(useItemEncryptor bool) error { + attributeActions := map[string]dbesdkstructuredencryptiontypes.CryptoAction{ + "partition_key": dbesdkstructuredencryptiontypes.CryptoActionSignOnly, + "sort_key": dbesdkstructuredencryptiontypes.CryptoActionSignOnly, + "attribute1": dbesdkstructuredencryptiontypes.CryptoActionEncryptAndSign, + "attribute2": dbesdkstructuredencryptiontypes.CryptoActionSignOnly, + ":attribute3": dbesdkstructuredencryptiontypes.CryptoActionDoNothing, + } + + allowedUnsignedAttributePrefix := ":" + + partitionKey := "partition_key" + sortKeyName := "sort_key" + algorithmSuiteID := mpltypes.DBEAlgorithmSuiteIdAlgAes256GcmHkdfSha512CommitKeyEcdsaP384SymsigHmacSha384 + + err := b.setupItemEncryptorClient(partitionKey, sortKeyName, allowedUnsignedAttributePrefix, algorithmSuiteID, attributeActions) + if err != nil { + return err + } + + // err = b.SetupDDB(partitionKey, sortKeyName, allowedUnsignedAttributePrefix, algorithmSuiteID, attributeActions) + // if err != nil { + // return err + // } + + log.Println("ESDK client initialized successfully") + return nil +} + +func (b *DBESDKBenchmark) SetupDDB(partitionKey, sortKeyName, allowedUnsignedAttributePrefix string, algorithmSuiteID mpltypes.DBEAlgorithmSuiteId, attributeActions map[string]dbesdkstructuredencryptiontypes.CryptoAction) error { + tableConfig := dbesdkdynamodbencryptiontypes.DynamoDbTableEncryptionConfig{ + LogicalTableName: b.Config.TableName, + PartitionKeyName: partitionKey, + SortKeyName: &sortKeyName, + AttributeActionsOnEncrypt: attributeActions, + Keyring: b.Keyring, + AllowedUnsignedAttributePrefix: &allowedUnsignedAttributePrefix, + AlgorithmSuiteId: &algorithmSuiteID, + } + tableConfigsMap := make(map[string]dbesdkdynamodbencryptiontypes.DynamoDbTableEncryptionConfig) + tableConfigsMap[b.Config.TableName] = tableConfig + listOfTableConfigs := dbesdkdynamodbencryptiontypes.DynamoDbTablesEncryptionConfig{ + TableEncryptionConfigs: tableConfigsMap, + } + + cfg, err := config.LoadDefaultConfig(context.TODO()) + if err != nil { + return fmt.Errorf("failed to load default config: %w", err) + } + + dbEsdkMiddleware, err := dbesdkmiddleware.NewDBEsdkMiddleware(listOfTableConfigs) + ddb := dynamodb.NewFromConfig(cfg, dbEsdkMiddleware.CreateMiddleware(), func(o *dynamodb.Options) { + o.EndpointResolverV2 = &resolverV2{} + }) + + b.DbesdkClient = ddb + + return nil +} + +func (b *DBESDKBenchmark) setupItemEncryptorClient(partitionKey, sortKeyName, allowedUnsignedAttributePrefix string, algorithmSuiteID mpltypes.DBEAlgorithmSuiteId, attributeActions map[string]dbesdkstructuredencryptiontypes.CryptoAction) error { + itemEncryptorConfig := dbesdkitemencryptortypes.DynamoDbItemEncryptorConfig{ + LogicalTableName: b.Config.TableName, + PartitionKeyName: partitionKey, + SortKeyName: &sortKeyName, + AttributeActionsOnEncrypt: attributeActions, + Keyring: b.Keyring, + AllowedUnsignedAttributePrefix: &allowedUnsignedAttributePrefix, + AlgorithmSuiteId: &algorithmSuiteID, + } + itemEncryptorClient, err := itemencryptor.NewClient(itemEncryptorConfig) + if err != nil { + return fmt.Errorf("failed to create item encryptor client: %w", err) + } + b.ItemEncryptorClient = itemEncryptorClient + return nil +} + +type resolverV2 struct { +} + +func (*resolverV2) ResolveEndpoint(ctx context.Context, params dynamodb.EndpointParameters) ( + smithyendpoints.Endpoint, error, +) { + u, err := url.Parse("http://localhost:8000") + if err != nil { + return smithyendpoints.Endpoint{}, err + } + return smithyendpoints.Endpoint{ + URI: *u, + }, nil +} + +// GenerateTestData creates test data of specified size +func (b *DBESDKBenchmark) GenerateTestData(size int) []byte { + data := make([]byte, size) + rand.Read(data) + return data +} diff --git a/db-esdk-performance-testing/benchmarks/go/benchmark/keyringsetup.go b/db-esdk-performance-testing/benchmarks/go/benchmark/keyringsetup.go new file mode 100644 index 000000000..da53309ee --- /dev/null +++ b/db-esdk-performance-testing/benchmarks/go/benchmark/keyringsetup.go @@ -0,0 +1,30 @@ +package benchmark + +import ( + "context" + "crypto/rand" + "fmt" + + mplsmithygenerated "github.com/aws/aws-cryptographic-material-providers-library/releases/go/mpl/awscryptographymaterialproviderssmithygenerated" + mpltypes "github.com/aws/aws-cryptographic-material-providers-library/releases/go/mpl/awscryptographymaterialproviderssmithygeneratedtypes" +) + +func SetupRawAESKeyring(matProv *mplsmithygenerated.Client) (mpltypes.IKeyring, error) { + key := make([]byte, 32) + if _, err := rand.Read(key); err != nil { + return nil, fmt.Errorf("failed to generate AES-256 key: %w", err) + } + + keyringInput := mpltypes.CreateRawAesKeyringInput{ + KeyName: "test-aes-256-key", + KeyNamespace: "DB-ESDK-performance-test", + WrappingKey: key, + WrappingAlg: mpltypes.AesWrappingAlgAlgAes256GcmIv12Tag16, + } + + keyring, err := matProv.CreateRawAesKeyring(context.Background(), keyringInput) + if err != nil { + return nil, fmt.Errorf("failed to create keyring: %w", err) + } + return keyring, nil +} diff --git a/db-esdk-performance-testing/benchmarks/go/benchmark/results.go b/db-esdk-performance-testing/benchmarks/go/benchmark/results.go new file mode 100644 index 000000000..c71e2ad98 --- /dev/null +++ b/db-esdk-performance-testing/benchmarks/go/benchmark/results.go @@ -0,0 +1,117 @@ +// Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. +// SPDX-License-Identifier: Apache-2.0 + +package benchmark + +import ( + "encoding/json" + "fmt" + "math" + "os" + "path/filepath" + "runtime" + "time" +) + +// BenchmarkResult represents the results of a single benchmark test +type BenchmarkResult struct { + TestName string `json:"test_name"` + Language string `json:"language"` + DataSize int `json:"data_size"` + Concurrency int `json:"concurrency"` + PutLatencyMs float64 `json:"put_latency_ms"` + GetLatencyMs float64 `json:"get_latency_ms"` + EndToEndLatencyMs float64 `json:"end_to_end_latency_ms"` + OpsPerSecond float64 `json:"ops_per_second"` + BytesPerSecond float64 `json:"bytes_per_second"` + PeakMemoryMB float64 `json:"peak_memory_mb"` + MemoryEfficiency float64 `json:"memory_efficiency_ratio"` + P50Latency float64 `json:"p50_latency"` + P95Latency float64 `json:"p95_latency"` + P99Latency float64 `json:"p99_latency"` + Timestamp string `json:"timestamp"` + GoVersion string `json:"go_version"` + CPUCount int `json:"cpu_count"` + TotalMemoryGB float64 `json:"total_memory_gb"` +} + +// MemorySample represents a single memory measurement +type MemorySample struct { + Timestamp time.Time + HeapMB float64 + MetricsAllocsMB float64 + MemStatsAllocsMB float64 +} + +// === Utility Functions === + +// Average calculates the average of a slice of float64 values +func Average(values []float64) float64 { + if len(values) == 0 { + return 0 + } + sum := 0.0 + for _, v := range values { + sum += v + } + return sum / float64(len(values)) +} + +// Percentile calculates the percentile of sorted values +func Percentile(sortedValues []float64, p float64) float64 { + if len(sortedValues) == 0 { + return 0 + } + if p <= 0 { + return sortedValues[0] + } + if p >= 100 { + return sortedValues[len(sortedValues)-1] + } + + index := (p / 100.0) * float64(len(sortedValues)-1) + lower := int(math.Floor(index)) + upper := int(math.Ceil(index)) + + if lower == upper { + return sortedValues[lower] + } + + weight := index - float64(lower) + return sortedValues[lower]*(1-weight) + sortedValues[upper]*weight +} + +// === Results Saving === + +// SaveResults saves benchmark results to JSON file +func (b *DBESDKBenchmark) SaveResults(outputPath string) error { + if err := os.MkdirAll(filepath.Dir(outputPath), 0755); err != nil { + return fmt.Errorf("failed to create output directory: %w", err) + } + + resultsData := map[string]interface{}{ + "metadata": map[string]interface{}{ + "language": "go", + "timestamp": time.Now().Format("2006-01-02 15:04:05"), + "go_version": runtime.Version(), + "cpu_count": b.CPUCount, + "total_memory_gb": b.TotalMemoryGB, + "total_tests": len(b.Results), + }, + "results": b.Results, + } + + file, err := os.Create(outputPath) + if err != nil { + return fmt.Errorf("failed to create output file: %w", err) + } + defer file.Close() + + encoder := json.NewEncoder(file) + encoder.SetIndent("", " ") + if err := encoder.Encode(resultsData); err != nil { + return fmt.Errorf("failed to encode results to JSON: %w", err) + } + + return nil +} diff --git a/db-esdk-performance-testing/benchmarks/go/benchmark/testRunners.go b/db-esdk-performance-testing/benchmarks/go/benchmark/testRunners.go new file mode 100644 index 000000000..ac7ab2055 --- /dev/null +++ b/db-esdk-performance-testing/benchmarks/go/benchmark/testRunners.go @@ -0,0 +1,352 @@ +package benchmark + +import ( + "fmt" + "log" + "runtime" + "runtime/metrics" + "sort" + "sync" + "time" + + "github.com/schollz/progressbar/v3" +) + +// === Test Orchestration === + +// runThroughputTests executes all throughput tests +func (b *DBESDKBenchmark) runThroughputTests(dataSizes []int, iterations int) { + log.Println("Running throughput tests...") + for _, dataSize := range dataSizes { + result, err := b.runThroughputTest(dataSize, iterations) + if err != nil { + log.Printf("Throughput test failed: %v", err) + continue + } + b.Results = append(b.Results, *result) + log.Printf("Throughput test completed: %.2f ops/sec", result.OpsPerSecond) + } +} + +// runMemoryTests executes all memory tests +func (b *DBESDKBenchmark) runMemoryTests(dataSizes []int) { + log.Println("Running memory tests...") + for _, dataSize := range dataSizes { + result, err := b.runMemoryTest(dataSize) + if err != nil { + log.Printf("Memory test failed: %v", err) + continue + } + b.Results = append(b.Results, *result) + log.Printf("Memory test completed: %.2f MB peak", result.PeakMemoryMB) + } +} + +// runConcurrencyTests executes all concurrency tests +func (b *DBESDKBenchmark) runConcurrencyTests(dataSizes []int, concurrencyLevels []int) { + log.Println("Running concurrency tests...") + for _, dataSize := range dataSizes { + for _, concurrency := range concurrencyLevels { + if concurrency > 1 { // Skip single-threaded + result, err := b.runConcurrentTest(dataSize, concurrency, 5) + if err != nil { + log.Printf("Concurrent test failed: %v", err) + continue + } + b.Results = append(b.Results, *result) + log.Printf("Concurrent test completed: %.2f ops/sec @ %d threads", result.OpsPerSecond, concurrency) + } + } + } +} + +// RunAllBenchmarks runs all configured benchmark tests +func (b *DBESDKBenchmark) RunAllBenchmarks() error { + log.Println("Starting comprehensive DB-ESDK benchmark suite") + + // Combine all data sizes + var dataSizes []int + for _, sizes := range [][]int{b.Config.DataSizes.Small, b.Config.DataSizes.Medium, b.Config.DataSizes.Large} { + dataSizes = append(dataSizes, sizes...) + } + + // Run test suites + if b.shouldRunTestType("throughput") { + b.runThroughputTests(dataSizes, b.Config.Iterations.Measurement) + } else { + log.Println("Skipping throughput tests (not in test_types)") + } + + if b.shouldRunTestType("memory") { + b.runMemoryTests(dataSizes) + } else { + log.Println("Skipping memory tests (not in test_types)") + } + + if b.shouldRunTestType("concurrency") { + b.runConcurrencyTests(dataSizes, b.Config.ConcurrencyLevels) + } else { + log.Println("Skipping concurrency tests (not in test_types)") + } + + log.Printf("Benchmark suite completed. Total results: %d", len(b.Results)) + return nil +} + +// === Memory Test Implementation === + +// runMemoryTest runs memory benchmark with continuous sampling +func (b *DBESDKBenchmark) runMemoryTest(dataSize int) (*BenchmarkResult, error) { + log.Printf("Running memory test - Size: %d bytes (%d iterations, continuous sampling)", dataSize, MemoryTestIterations) + + data := b.GenerateTestData(dataSize) + + // Setup runtime/metrics tracking + samples := make([]metrics.Sample, 2) + samples[0].Name = "/memory/classes/heap/objects:bytes" + samples[1].Name = "/gc/heap/allocs:bytes" + + var peakHeap, peakAllocations float64 + var avgHeapValues []float64 + + // Run iterations + for i := 0; i < MemoryTestIterations; i++ { + runtime.GC() + time.Sleep(GCSettleTimeMs * time.Millisecond) + + // Start continuous sampling + stopSampling := make(chan bool) + var continuousSamples []MemorySample + var samplingMutex sync.Mutex + + // Get baseline + metrics.Read(samples) + beforeHeap := samples[0].Value.Uint64() + beforeAllocs := samples[1].Value.Uint64() + + go func() { + sampledData := b.sampleMemoryContinuously(beforeHeap, beforeAllocs, stopSampling) + samplingMutex.Lock() + continuousSamples = sampledData + samplingMutex.Unlock() + }() + + // Run operation + operationStart := time.Now() + _, _, err := b.runItemEncryptorCycle(data) + operationDuration := time.Since(operationStart) + + close(stopSampling) + time.Sleep(FinalSampleWaitMs * time.Millisecond) + + if err != nil { + log.Printf("Iteration %d failed: %v", i+1, err) + continue + } + + // Analyze samples + samplingMutex.Lock() + var iterPeakHeap, iterTotalAllocs, iterAvgHeap float64 + if len(continuousSamples) > 0 { + var heapSum float64 + for _, s := range continuousSamples { + if s.HeapMB > iterPeakHeap { + iterPeakHeap = s.HeapMB + } + if s.MetricsAllocsMB > iterTotalAllocs { + iterTotalAllocs = s.MetricsAllocsMB + } + heapSum += s.HeapMB + } + iterAvgHeap = heapSum / float64(len(continuousSamples)) + } + samplingMutex.Unlock() + + // Update global metrics + if iterPeakHeap > peakHeap { + peakHeap = iterPeakHeap + } + if iterTotalAllocs > peakAllocations { + peakAllocations = iterTotalAllocs + } + avgHeapValues = append(avgHeapValues, iterAvgHeap) + + log.Printf("=== Iteration %d === Peak Heap: %.2f MB, Total Allocs: %.2f MB, Avg Heap: %.2f MB (%v, %d samples)", + i+1, iterPeakHeap, iterTotalAllocs, iterAvgHeap, operationDuration, len(continuousSamples)) + } + + if len(avgHeapValues) == 0 { + return nil, fmt.Errorf("all memory test iterations failed") + } + + overallAvgHeap := Average(avgHeapValues) + memoryEfficiency := float64(dataSize) / (overallAvgHeap * 1024 * 1024) + if overallAvgHeap == 0 { + memoryEfficiency = 0 + } + + log.Printf("\nMemory Summary:") + log.Printf("- Absolute Peak Heap: %.2f MB (across all runs)", peakHeap) + log.Printf("- Average Heap: %.2f MB (across all runs)", overallAvgHeap) + log.Printf("- Total Allocations: %.2f MB (max across all runs)", peakAllocations) + + result := &BenchmarkResult{ + TestName: "memory", + Language: "go", + DataSize: dataSize, + Concurrency: 1, + PeakMemoryMB: peakHeap, + MemoryEfficiency: memoryEfficiency, + Timestamp: time.Now().Format("2006-01-02 15:04:05"), + GoVersion: runtime.Version(), + CPUCount: b.CPUCount, + TotalMemoryGB: b.TotalMemoryGB, + } + + return result, nil +} + +// === Concurrent Test Implementation === + +// runConcurrentTest runs concurrent operations benchmark test +func (b *DBESDKBenchmark) runConcurrentTest(dataSize int, concurrency int, iterationsPerWorker int) (*BenchmarkResult, error) { + log.Printf("Running concurrent test - Size: %d bytes, Concurrency: %d", dataSize, concurrency) + + data := b.GenerateTestData(dataSize) + var allTimes []float64 + var timesMutex sync.Mutex + var wg sync.WaitGroup + + errorChan := make(chan error, concurrency) + startTime := time.Now() + + // Launch workers + for i := 0; i < concurrency; i++ { + wg.Add(1) + go func(workerID int) { + defer wg.Done() + + var workerTimes []float64 + for j := 0; j < iterationsPerWorker; j++ { + iterStart := time.Now() + _, _, err := b.runItemEncryptorCycle(data) + if err != nil { + errorChan <- fmt.Errorf("worker %d iteration %d failed: %w", workerID, j, err) + return + } + workerTimes = append(workerTimes, time.Since(iterStart).Seconds()*1000) + } + + timesMutex.Lock() + allTimes = append(allTimes, workerTimes...) + timesMutex.Unlock() + }(i) + } + + wg.Wait() + totalDuration := time.Since(startTime).Seconds() + + // Check for errors + select { + case err := <-errorChan: + return nil, err + default: + } + + // Calculate metrics + totalOps := concurrency * iterationsPerWorker + totalBytes := int64(totalOps * dataSize) + + sort.Float64s(allTimes) + result := &BenchmarkResult{ + TestName: "concurrent", + Language: "go", + DataSize: dataSize, + Concurrency: concurrency, + EndToEndLatencyMs: Average(allTimes), + OpsPerSecond: float64(totalOps) / totalDuration, + BytesPerSecond: float64(totalBytes) / totalDuration, + P50Latency: Percentile(allTimes, 0.50), + P95Latency: Percentile(allTimes, 0.95), + P99Latency: Percentile(allTimes, 0.99), + Timestamp: time.Now().Format("2006-01-02 15:04:05"), + GoVersion: runtime.Version(), + CPUCount: b.CPUCount, + TotalMemoryGB: b.TotalMemoryGB, + } + + log.Printf("Concurrent test completed - Ops/sec: %.2f, Avg latency: %.2f ms", + result.OpsPerSecond, result.EndToEndLatencyMs) + + return result, nil +} + +// === Throughput Test Implementation === + +// runThroughputTest runs throughput benchmark test +func (b *DBESDKBenchmark) runThroughputTest(dataSize int, iterations int) (*BenchmarkResult, error) { + log.Printf("Running throughput test - Size: %d bytes, Iterations: %d", dataSize, iterations) + + testData := b.GenerateTestData(dataSize) + + // Warmup + for i := 0; i < b.Config.Iterations.Warmup; i++ { + if _, _, err := b.runItemEncryptorCycle(testData); err != nil { + return nil, fmt.Errorf("warmup iteration %d failed: %w", i, err) + } + } + + // Measurement runs + var putLatencies, getLatencies, endToEndLatencies []float64 + var totalBytes int64 + + bar := progressbar.NewOptions(iterations, + progressbar.OptionSetDescription("Throughput test"), + progressbar.OptionShowCount(), + progressbar.OptionSetWidth(50), + ) + + startTime := time.Now() + for i := 0; i < iterations; i++ { + iterationStart := time.Now() + putMs, getMs, err := b.runItemEncryptorCycle(testData) + if err != nil { + return nil, fmt.Errorf("measurement iteration %d failed: %w", i, err) + } + iterationDuration := time.Since(iterationStart).Seconds() * 1000 + + putLatencies = append(putLatencies, putMs) + getLatencies = append(getLatencies, getMs) + endToEndLatencies = append(endToEndLatencies, iterationDuration) + totalBytes += int64(dataSize) + + bar.Add(1) + } + totalDuration := time.Since(startTime).Seconds() + + // Calculate metrics + sort.Float64s(endToEndLatencies) + result := &BenchmarkResult{ + TestName: "throughput", + Language: "go", + DataSize: dataSize, + Concurrency: 1, + PutLatencyMs: Average(putLatencies), + GetLatencyMs: Average(getLatencies), + EndToEndLatencyMs: Average(endToEndLatencies), + OpsPerSecond: float64(iterations) / totalDuration, + BytesPerSecond: float64(totalBytes) / totalDuration, + P50Latency: Percentile(endToEndLatencies, 0.50), + P95Latency: Percentile(endToEndLatencies, 0.95), + P99Latency: Percentile(endToEndLatencies, 0.99), + Timestamp: time.Now().Format("2006-01-02 15:04:05"), + GoVersion: runtime.Version(), + CPUCount: b.CPUCount, + TotalMemoryGB: b.TotalMemoryGB, + } + + log.Printf("Throughput test completed - Ops/sec: %.2f, MB/sec: %.2f", + result.OpsPerSecond, result.BytesPerSecond/(1024*1024)) + + return result, nil +} diff --git a/db-esdk-performance-testing/benchmarks/go/go.mod b/db-esdk-performance-testing/benchmarks/go/go.mod new file mode 100644 index 000000000..e521a2d68 --- /dev/null +++ b/db-esdk-performance-testing/benchmarks/go/go.mod @@ -0,0 +1,50 @@ +module github.com/aws/aws-database-encryption-sdk-dynamodb/db-esdk-performance-testing/benchmarks/go + +go 1.23.2 + +toolchain go1.24.4 + +replace github.com/aws/aws-database-encryption-sdk-dynamodb/releases/go/dynamodb-esdk => ../../../DynamoDbEncryption/runtimes/go/ImplementationFromDafny-go/ + +require ( + github.com/aws/aws-cryptographic-material-providers-library/releases/go/mpl v0.2.2 + github.com/aws/aws-database-encryption-sdk-dynamodb/releases/go/dynamodb-esdk v0.0.0 + github.com/aws/aws-sdk-go-v2 v1.38.1 + github.com/aws/aws-sdk-go-v2/config v1.31.2 + github.com/aws/aws-sdk-go-v2/service/dynamodb v1.49.1 + github.com/aws/smithy-go v1.22.5 + github.com/schollz/progressbar/v3 v3.14.1 + github.com/shirou/gopsutil/v3 v3.23.12 + gopkg.in/yaml.v3 v3.0.1 +) + +require ( + github.com/aws/aws-cryptographic-material-providers-library/releases/go/dynamodb v0.2.2 // indirect + github.com/aws/aws-cryptographic-material-providers-library/releases/go/kms v0.2.2 // indirect + github.com/aws/aws-cryptographic-material-providers-library/releases/go/primitives v0.2.2 // indirect + github.com/aws/aws-cryptographic-material-providers-library/releases/go/smithy-dafny-standard-library v0.2.2 // indirect + github.com/aws/aws-sdk-go-v2/credentials v1.18.6 // indirect + github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.18.4 // indirect + github.com/aws/aws-sdk-go-v2/internal/configsources v1.4.4 // indirect + github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.7.4 // indirect + github.com/aws/aws-sdk-go-v2/internal/ini v1.8.3 // indirect + github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.13.0 // indirect + github.com/aws/aws-sdk-go-v2/service/internal/endpoint-discovery v1.11.4 // indirect + github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.13.4 // indirect + github.com/aws/aws-sdk-go-v2/service/kms v1.44.2 // indirect + github.com/aws/aws-sdk-go-v2/service/sso v1.28.2 // indirect + github.com/aws/aws-sdk-go-v2/service/ssooidc v1.33.2 // indirect + github.com/aws/aws-sdk-go-v2/service/sts v1.38.0 // indirect + github.com/dafny-lang/DafnyRuntimeGo/v4 v4.11.0 // indirect + github.com/go-ole/go-ole v1.2.6 // indirect + github.com/google/uuid v1.6.0 // indirect + github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0 // indirect + github.com/mitchellh/colorstring v0.0.0-20190213212951-d06e56a500db // indirect + github.com/power-devops/perfstat v0.0.0-20210106213030-5aafc221ea8c // indirect + github.com/rivo/uniseg v0.4.4 // indirect + github.com/tklauser/go-sysconf v0.3.12 // indirect + github.com/tklauser/numcpus v0.6.1 // indirect + github.com/yusufpapurcu/wmi v1.2.3 // indirect + golang.org/x/sys v0.15.0 // indirect + golang.org/x/term v0.14.0 // indirect +) diff --git a/db-esdk-performance-testing/benchmarks/go/go.sum b/db-esdk-performance-testing/benchmarks/go/go.sum new file mode 100644 index 000000000..5c23c6894 --- /dev/null +++ b/db-esdk-performance-testing/benchmarks/go/go.sum @@ -0,0 +1,103 @@ +github.com/aws/aws-cryptographic-material-providers-library/releases/go/dynamodb v0.2.2 h1:1CYvKblXRaPB9B0cdN/xWVOXvii2AQHgdcbTlI5F8Oc= +github.com/aws/aws-cryptographic-material-providers-library/releases/go/dynamodb v0.2.2/go.mod h1:vb/jlzf5XQSD5O3Po50VX6j6JyzcWs3wPoV7foewmJs= +github.com/aws/aws-cryptographic-material-providers-library/releases/go/kms v0.2.2 h1:0x9qTjQeW8fkP+/kuRw2drLDZM617rr8h6kcUetBjKE= +github.com/aws/aws-cryptographic-material-providers-library/releases/go/kms v0.2.2/go.mod h1:2wGHS+a/Dg21W3cnFDYbOu33d6eQUS52Ff/uAE2vIu8= +github.com/aws/aws-cryptographic-material-providers-library/releases/go/mpl v0.2.2 h1:gXYtIJfwt+5gOmo7zg/TDb0l1cz5XgnWR0/opB0OyyA= +github.com/aws/aws-cryptographic-material-providers-library/releases/go/mpl v0.2.2/go.mod h1:9yccmncslXtxhE4vyg1ZKaTWEe5xyNljrt3glFtMN4g= +github.com/aws/aws-cryptographic-material-providers-library/releases/go/primitives v0.2.2 h1:tBPXcmQVmf0ILx5eY++l64+yp04AFlHeKqpli0YDQBc= +github.com/aws/aws-cryptographic-material-providers-library/releases/go/primitives v0.2.2/go.mod h1:mSUejB7V5Wo23naCw2ORAJ+5ZJkyaSvB6hQbKPVXNuA= +github.com/aws/aws-cryptographic-material-providers-library/releases/go/smithy-dafny-standard-library v0.2.2 h1:k/OqY+NJcTlFByY1WcM6dF5ZC4kIZtZ8b3A9kRVAj8Y= +github.com/aws/aws-cryptographic-material-providers-library/releases/go/smithy-dafny-standard-library v0.2.2/go.mod h1:j4QF5oVY9L1yNZrzoDu3l3d8TRh53uBw3FLZCL7xCTk= +github.com/aws/aws-sdk-go-v2 v1.38.1 h1:j7sc33amE74Rz0M/PoCpsZQ6OunLqys/m5antM0J+Z8= +github.com/aws/aws-sdk-go-v2 v1.38.1/go.mod h1:9Q0OoGQoboYIAJyslFyF1f5K1Ryddop8gqMhWx/n4Wg= +github.com/aws/aws-sdk-go-v2/config v1.31.2 h1:NOaSZpVGEH2Np/c1toSeW0jooNl+9ALmsUTZ8YvkJR0= +github.com/aws/aws-sdk-go-v2/config v1.31.2/go.mod h1:17ft42Yb2lF6OigqSYiDAiUcX4RIkEMY6XxEMJsrAes= +github.com/aws/aws-sdk-go-v2/credentials v1.18.6 h1:AmmvNEYrru7sYNJnp3pf57lGbiarX4T9qU/6AZ9SucU= +github.com/aws/aws-sdk-go-v2/credentials v1.18.6/go.mod h1:/jdQkh1iVPa01xndfECInp1v1Wnp70v3K4MvtlLGVEc= +github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.18.4 h1:lpdMwTzmuDLkgW7086jE94HweHCqG+uOJwHf3LZs7T0= +github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.18.4/go.mod h1:9xzb8/SV62W6gHQGC/8rrvgNXU6ZoYM3sAIJCIrXJxY= +github.com/aws/aws-sdk-go-v2/internal/configsources v1.4.4 h1:IdCLsiiIj5YJ3AFevsewURCPV+YWUlOW8JiPhoAy8vg= +github.com/aws/aws-sdk-go-v2/internal/configsources v1.4.4/go.mod h1:l4bdfCD7XyyZA9BolKBo1eLqgaJxl0/x91PL4Yqe0ao= +github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.7.4 h1:j7vjtr1YIssWQOMeOWRbh3z8g2oY/xPjnZH2gLY4sGw= +github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.7.4/go.mod h1:yDmJgqOiH4EA8Hndnv4KwAo8jCGTSnM5ASG1nBI+toA= +github.com/aws/aws-sdk-go-v2/internal/ini v1.8.3 h1:bIqFDwgGXXN1Kpp99pDOdKMTTb5d2KyU5X/BZxjOkRo= +github.com/aws/aws-sdk-go-v2/internal/ini v1.8.3/go.mod h1:H5O/EsxDWyU+LP/V8i5sm8cxoZgc2fdNR9bxlOFrQTo= +github.com/aws/aws-sdk-go-v2/service/dynamodb v1.49.1 h1:0RqS5X7EodJzOenoY4V3LUSp9PirELO2ZOpOZbMldco= +github.com/aws/aws-sdk-go-v2/service/dynamodb v1.49.1/go.mod h1:VRp/OeQolnQD9GfNgdSf3kU5vbg708PF6oPHh2bq3hc= +github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.13.0 h1:6+lZi2JeGKtCraAj1rpoZfKqnQ9SptseRZioejfUOLM= +github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.13.0/go.mod h1:eb3gfbVIxIoGgJsi9pGne19dhCBpK6opTYpQqAmdy44= +github.com/aws/aws-sdk-go-v2/service/internal/endpoint-discovery v1.11.4 h1:upi++G3fQCAUBXQe58TbjXmdVPwrqMnRQMThOAIz7KM= +github.com/aws/aws-sdk-go-v2/service/internal/endpoint-discovery v1.11.4/go.mod h1:swb+GqWXTZMOyVV9rVePAUu5L80+X5a+Lui1RNOyUFo= +github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.13.4 h1:ueB2Te0NacDMnaC+68za9jLwkjzxGWm0KB5HTUHjLTI= +github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.13.4/go.mod h1:nLEfLnVMmLvyIG58/6gsSA03F1voKGaCfHV7+lR8S7s= +github.com/aws/aws-sdk-go-v2/service/kms v1.44.2 h1:yTtMSIGWk8KzPDX2pS9k7wNCPKiNWpiJ9DdB2mCAMzo= +github.com/aws/aws-sdk-go-v2/service/kms v1.44.2/go.mod h1:zgkQ8ige7qtxldA4cGtiXdbql3dBo4TfsP6uQyHwq0E= +github.com/aws/aws-sdk-go-v2/service/sso v1.28.2 h1:ve9dYBB8CfJGTFqcQ3ZLAAb/KXWgYlgu/2R2TZL2Ko0= +github.com/aws/aws-sdk-go-v2/service/sso v1.28.2/go.mod h1:n9bTZFZcBa9hGGqVz3i/a6+NG0zmZgtkB9qVVFDqPA8= +github.com/aws/aws-sdk-go-v2/service/ssooidc v1.33.2 h1:pd9G9HQaM6UZAZh19pYOkpKSQkyQQ9ftnl/LttQOcGI= +github.com/aws/aws-sdk-go-v2/service/ssooidc v1.33.2/go.mod h1:eknndR9rU8UpE/OmFpqU78V1EcXPKFTTm5l/buZYgvM= +github.com/aws/aws-sdk-go-v2/service/sts v1.38.0 h1:iV1Ko4Em/lkJIsoKyGfc0nQySi+v0Udxr6Igq+y9JZc= +github.com/aws/aws-sdk-go-v2/service/sts v1.38.0/go.mod h1:bEPcjW7IbolPfK67G1nilqWyoxYMSPrDiIQ3RdIdKgo= +github.com/aws/smithy-go v1.22.5 h1:P9ATCXPMb2mPjYBgueqJNCA5S9UfktsW0tTxi+a7eqw= +github.com/aws/smithy-go v1.22.5/go.mod h1:t1ufH5HMublsJYulve2RKmHDC15xu1f26kHCp/HgceI= +github.com/dafny-lang/DafnyRuntimeGo/v4 v4.11.0 h1:wJhHuhD9thOc0GXojfW8DJ/n7G8prW+1nUL5O3lvzs0= +github.com/dafny-lang/DafnyRuntimeGo/v4 v4.11.0/go.mod h1:l2Tm4N2DKuq3ljONC2vOATeM9PUpXbIc8SgXdwwqEto= +github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= +github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/go-ole/go-ole v1.2.6 h1:/Fpf6oFPoeFik9ty7siob0G6Ke8QvQEuVcuChpwXzpY= +github.com/go-ole/go-ole v1.2.6/go.mod h1:pprOEPIfldk/42T2oK7lQ4v4JSDwmV0As9GaiUsvbm0= +github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= +github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= +github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= +github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= +github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/k0kubun/go-ansi v0.0.0-20180517002512-3bf9e2903213/go.mod h1:vNUNkEQ1e29fT/6vq2aBdFsgNPmy8qMdSay1npru+Sw= +github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0 h1:6E+4a0GO5zZEnZ81pIr0yLvtUWk2if982qA3F3QD6H4= +github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0/go.mod h1:zJYVVT2jmtg6P3p1VtQj7WsuWi/y4VnjVBn7F8KPB3I= +github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= +github.com/mitchellh/colorstring v0.0.0-20190213212951-d06e56a500db h1:62I3jR2EmQ4l5rM/4FEfDWcRD+abF5XlKShorW5LRoQ= +github.com/mitchellh/colorstring v0.0.0-20190213212951-d06e56a500db/go.mod h1:l0dey0ia/Uv7NcFFVbCLtqEBQbrT4OCwCSKTEv6enCw= +github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/power-devops/perfstat v0.0.0-20210106213030-5aafc221ea8c h1:ncq/mPwQF4JjgDlrVEn3C11VoGHZN7m8qihwgMEtzYw= +github.com/power-devops/perfstat v0.0.0-20210106213030-5aafc221ea8c/go.mod h1:OmDBASR4679mdNQnz2pUhc2G8CO2JrUAVFDRBDP/hJE= +github.com/rivo/uniseg v0.4.4 h1:8TfxU8dW6PdqD27gjM8MVNuicgxIjxpm4K7x4jp8sis= +github.com/rivo/uniseg v0.4.4/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88= +github.com/schollz/progressbar/v3 v3.14.1 h1:VD+MJPCr4s3wdhTc7OEJ/Z3dAeBzJ7yKH/P4lC5yRTI= +github.com/schollz/progressbar/v3 v3.14.1/go.mod h1:Zc9xXneTzWXF81TGoqL71u0sBPjULtEHYtj/WVgVy8E= +github.com/shirou/gopsutil/v3 v3.23.12 h1:z90NtUkp3bMtmICZKpC4+WaknU1eXtp5vtbQ11DgpE4= +github.com/shirou/gopsutil/v3 v3.23.12/go.mod h1:1FrWgea594Jp7qmjHUUPlJDTPgcsb9mGnXDxavtikzM= +github.com/shoenig/go-m1cpu v0.1.6/go.mod h1:1JJMcUBvfNwpq05QDQVAnx3gUHr9IYF7GNg9SUEw2VQ= +github.com/shoenig/test v0.6.4/go.mod h1:byHiCGXqrVaflBLAMq/srcZIHynQPQgeyvkvXnjqq0k= +github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= +github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= +github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= +github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= +github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk= +github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= +github.com/tklauser/go-sysconf v0.3.12 h1:0QaGUFOdQaIVdPgfITYzaTegZvdCjmYO52cSFAEVmqU= +github.com/tklauser/go-sysconf v0.3.12/go.mod h1:Ho14jnntGE1fpdOqQEEaiKRpvIavV0hSfmBq8nJbHYI= +github.com/tklauser/numcpus v0.6.1 h1:ng9scYS7az0Bk4OZLvrNXNSAO2Pxr1XXRAPyjhIx+Fk= +github.com/tklauser/numcpus v0.6.1/go.mod h1:1XfjsgE2zo8GVw7POkMbHENHzVg3GzmoZ9fESEdAacY= +github.com/yusufpapurcu/wmi v1.2.3 h1:E1ctvB7uKFMOJw3fdOW32DwGE9I7t++CRUEMKvFoFiw= +github.com/yusufpapurcu/wmi v1.2.3/go.mod h1:SBZ9tNy3G9/m5Oi98Zks0QjeHVDvuK0qfxQmPyzfmi0= +golang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20201204225414-ed752295db88/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.14.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.15.0 h1:h48lPFYpsTvQJZF4EKyI4aLHaev3CxivZmv7yZig9pc= +golang.org/x/sys v0.15.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/term v0.14.0 h1:LGK9IlZ8T9jvdy6cTdfKUCltatMFOehAQo9SRC46UQ8= +golang.org/x/term v0.14.0/go.mod h1:TySc+nGkYR6qt8km8wUhuFRTVSMIX3XPR58y2lC8vww= +golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= +gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/db-esdk-performance-testing/benchmarks/go/main.go b/db-esdk-performance-testing/benchmarks/go/main.go new file mode 100644 index 000000000..e676dc8fe --- /dev/null +++ b/db-esdk-performance-testing/benchmarks/go/main.go @@ -0,0 +1,104 @@ +// Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. +// SPDX-License-Identifier: Apache-2.0 + +package main + +import ( + "context" + "flag" + "fmt" + "log" + + "github.com/aws/aws-database-encryption-sdk-dynamodb/db-esdk-performance-testing/benchmarks/go/benchmark" + "github.com/aws/aws-sdk-go-v2/aws" + "github.com/aws/aws-sdk-go-v2/service/dynamodb" + "github.com/aws/aws-sdk-go-v2/service/dynamodb/types" +) + +func main() { + // Parse command line arguments + configPath := flag.String("config", "../config/test-scenarios.yaml", "Path to test configuration file") + outputPath := flag.String("output", "../results/raw-data/go_results.json", "Path to output results file") + quick := flag.Bool("quick", false, "Run quick test with reduced iterations") + flag.Parse() + + // Initialize benchmark + bench, err := benchmark.New(*configPath) + if err != nil { + log.Fatalf("Failed to initialize benchmark: %v", err) + } + + // create dynamodb table + // CreateTable(bench.DbesdkClient, bench.Config.TableName) + + // Adjust config for quick test + if *quick { + if bench.Config.QuickConfig == nil { + log.Fatalf("Quick mode requested but no quick_config found in config file") + } + bench.Config.Iterations.Measurement = bench.Config.QuickConfig.Iterations.Measurement + bench.Config.Iterations.Warmup = bench.Config.QuickConfig.Iterations.Warmup + bench.Config.DataSizes.Small = bench.Config.QuickConfig.DataSizes.Small + bench.Config.DataSizes.Medium = []int{} + bench.Config.DataSizes.Large = []int{} + bench.Config.ConcurrencyLevels = bench.Config.QuickConfig.ConcurrencyLevels + } + + // Run benchmarks + if err := bench.RunAllBenchmarks(); err != nil { + log.Fatalf("Benchmark failed: %v", err) + } + + // Save results + if err := bench.SaveResults(*outputPath); err != nil { + log.Fatalf("Failed to save results: %v", err) + } + + // Print summary + fmt.Printf("\n=== ESDK Go Benchmark Summary ===\n") + fmt.Printf("Total tests completed: %d\n", len(bench.Results)) + fmt.Printf("Results saved to: %s\n", *outputPath) + + if len(bench.Results) > 0 { + var maxThroughput float64 + for _, result := range bench.Results { + if result.TestName == "throughput" && result.OpsPerSecond > maxThroughput { + maxThroughput = result.OpsPerSecond + } + } + if maxThroughput > 0 { + fmt.Printf("Maximum throughput: %.2f ops/sec\n", maxThroughput) + } + } +} + +// Create DynamoDB table +func CreateTable(dynamodbClient *dynamodb.Client, tableName string) error { + input := &dynamodb.CreateTableInput{ + TableName: &tableName, + KeySchema: []types.KeySchemaElement{ + { + AttributeName: aws.String("partition_key"), + KeyType: types.KeyTypeHash, + }, + { + AttributeName: aws.String("sort_key"), + KeyType: types.KeyTypeRange, + }, + }, + AttributeDefinitions: []types.AttributeDefinition{ + { + AttributeName: aws.String("partition_key"), + AttributeType: types.ScalarAttributeTypeS, + }, + { + AttributeName: aws.String("sort_key"), + AttributeType: types.ScalarAttributeTypeN, + }, + }, + BillingMode: types.BillingModePayPerRequest, + } + + _, err := dynamodbClient.CreateTable(context.Background(), input) + return err +} diff --git a/db-esdk-performance-testing/benchmarks/results/raw-data/go_results.json b/db-esdk-performance-testing/benchmarks/results/raw-data/go_results.json new file mode 100644 index 000000000..1bfde3acb --- /dev/null +++ b/db-esdk-performance-testing/benchmarks/results/raw-data/go_results.json @@ -0,0 +1,452 @@ +{ + "metadata": { + "cpu_count": 10, + "go_version": "go1.24.4", + "language": "go", + "timestamp": "2025-09-08 17:21:33", + "total_memory_gb": 32, + "total_tests": 22 + }, + "results": [ + { + "test_name": "throughput", + "language": "go", + "data_size": 1024, + "concurrency": 1, + "put_latency_ms": 1.2055002, + "get_latency_ms": 1.1074083999999997, + "end_to_end_latency_ms": 2.3190831, + "ops_per_second": 426.4074109608025, + "bytes_per_second": 436641.18882386177, + "peak_memory_mb": 0, + "memory_efficiency_ratio": 0, + "p50_latency": 1.8033442349999997, + "p95_latency": 1.8057168464999998, + "p99_latency": 1.8059277453, + "timestamp": "2025-09-08 17:17:10", + "go_version": "go1.24.4", + "cpu_count": 10, + "total_memory_gb": 32 + }, + { + "test_name": "throughput", + "language": "go", + "data_size": 5120, + "concurrency": 1, + "put_latency_ms": 1.3215625, + "get_latency_ms": 1.2667, + "end_to_end_latency_ms": 2.5952664000000003, + "ops_per_second": 381.1810896061446, + "bytes_per_second": 1951647.1787834605, + "peak_memory_mb": 0, + "memory_efficiency_ratio": 0, + "p50_latency": 2.21371986, + "p95_latency": 2.2185680339999996, + "p99_latency": 2.2189989827999996, + "timestamp": "2025-09-08 17:17:10", + "go_version": "go1.24.4", + "cpu_count": 10, + "total_memory_gb": 32 + }, + { + "test_name": "throughput", + "language": "go", + "data_size": 10240, + "concurrency": 1, + "put_latency_ms": 1.7353626000000002, + "get_latency_ms": 1.1622249, + "end_to_end_latency_ms": 2.9043833999999995, + "ops_per_second": 341.31829275593566, + "bytes_per_second": 3495099.317820781, + "peak_memory_mb": 0, + "memory_efficiency_ratio": 0, + "p50_latency": 2.470834375, + "p95_latency": 2.4729353125, + "p99_latency": 2.4731220625000003, + "timestamp": "2025-09-08 17:17:10", + "go_version": "go1.24.4", + "cpu_count": 10, + "total_memory_gb": 32 + }, + { + "test_name": "throughput", + "language": "go", + "data_size": 102400, + "concurrency": 1, + "put_latency_ms": 4.919158400000001, + "get_latency_ms": 3.2727707, + "end_to_end_latency_ms": 8.2059167, + "ops_per_second": 121.30469213099616, + "bytes_per_second": 12421600.474214006, + "peak_memory_mb": 0, + "memory_efficiency_ratio": 0, + "p50_latency": 7.230385624999999, + "p95_latency": 7.239057687499999, + "p99_latency": 7.2398285375, + "timestamp": "2025-09-08 17:17:10", + "go_version": "go1.24.4", + "cpu_count": 10, + "total_memory_gb": 32 + }, + { + "test_name": "throughput", + "language": "go", + "data_size": 512000, + "concurrency": 1, + "put_latency_ms": 20.124712600000002, + "get_latency_ms": 12.5600915, + "end_to_end_latency_ms": 32.714891800000004, + "ops_per_second": 30.52312432051138, + "bytes_per_second": 15627839.652101826, + "peak_memory_mb": 0, + "memory_efficiency_ratio": 0, + "p50_latency": 22.710098655, + "p95_latency": 22.7176502445, + "p99_latency": 22.7183214969, + "timestamp": "2025-09-08 17:17:11", + "go_version": "go1.24.4", + "cpu_count": 10, + "total_memory_gb": 32 + }, + { + "test_name": "throughput", + "language": "go", + "data_size": 1048576, + "concurrency": 1, + "put_latency_ms": 32.773429300000004, + "get_latency_ms": 23.1208751, + "end_to_end_latency_ms": 55.945937400000005, + "ops_per_second": 17.85900051210684, + "bytes_per_second": 18726519.32098294, + "peak_memory_mb": 0, + "memory_efficiency_ratio": 0, + "p50_latency": 45.05813311, + "p95_latency": 45.073440409, + "p99_latency": 45.0748010578, + "timestamp": "2025-09-08 17:17:11", + "go_version": "go1.24.4", + "cpu_count": 10, + "total_memory_gb": 32 + }, + { + "test_name": "throughput", + "language": "go", + "data_size": 10000000, + "concurrency": 1, + "put_latency_ms": 281.5082168, + "get_latency_ms": 186.33822500000002, + "end_to_end_latency_ms": 468.230175, + "ops_per_second": 2.135438933066375, + "bytes_per_second": 21354389.33066375, + "peak_memory_mb": 0, + "memory_efficiency_ratio": 0, + "p50_latency": 352.642489905, + "p95_latency": 352.7731311195, + "p99_latency": 352.78474367190006, + "timestamp": "2025-09-08 17:17:19", + "go_version": "go1.24.4", + "cpu_count": 10, + "total_memory_gb": 32 + }, + { + "test_name": "throughput", + "language": "go", + "data_size": 10485760, + "concurrency": 1, + "put_latency_ms": 290.71484570000007, + "get_latency_ms": 186.7133917, + "end_to_end_latency_ms": 477.81767929999995, + "ops_per_second": 2.092597819727563, + "bytes_per_second": 21942478.51418649, + "peak_memory_mb": 0, + "memory_efficiency_ratio": 0, + "p50_latency": 369.19260386, + "p95_latency": 369.223372034, + "p99_latency": 369.22610698280005, + "timestamp": "2025-09-08 17:17:26", + "go_version": "go1.24.4", + "cpu_count": 10, + "total_memory_gb": 32 + }, + { + "test_name": "throughput", + "language": "go", + "data_size": 52428800, + "concurrency": 1, + "put_latency_ms": 1422.3722624999998, + "get_latency_ms": 883.8290959, + "end_to_end_latency_ms": 2308.1340541, + "ops_per_second": 0.4332393293770216, + "bytes_per_second": 22714218.15204199, + "peak_memory_mb": 0, + "memory_efficiency_ratio": 0, + "p50_latency": 1791.3485099999998, + "p95_latency": 1791.9986565, + "p99_latency": 1792.0564473, + "timestamp": "2025-09-08 17:18:01", + "go_version": "go1.24.4", + "cpu_count": 10, + "total_memory_gb": 32 + }, + { + "test_name": "throughput", + "language": "go", + "data_size": 104857600, + "concurrency": 1, + "put_latency_ms": 3072.2044375000005, + "get_latency_ms": 2134.7866541000003, + "end_to_end_latency_ms": 5217.718212499999, + "ops_per_second": 0.19165258950990396, + "bytes_per_second": 20096230.569793705, + "peak_memory_mb": 0, + "memory_efficiency_ratio": 0, + "p50_latency": 3606.24030625, + "p95_latency": 3615.380194375, + "p99_latency": 3616.192628875, + "timestamp": "2025-09-08 17:19:18", + "go_version": "go1.24.4", + "cpu_count": 10, + "total_memory_gb": 32 + }, + { + "test_name": "throughput", + "language": "go", + "data_size": 100000000, + "concurrency": 1, + "put_latency_ms": 2864.5441333000003, + "get_latency_ms": 1820.2341794, + "end_to_end_latency_ms": 4690.7853166, + "ops_per_second": 0.213181164618029, + "bytes_per_second": 21318116.4618029, + "peak_memory_mb": 0, + "memory_efficiency_ratio": 0, + "p50_latency": 3478.5917336099997, + "p95_latency": 3479.9986816589994, + "p99_latency": 3480.1237437078003, + "timestamp": "2025-09-08 17:20:31", + "go_version": "go1.24.4", + "cpu_count": 10, + "total_memory_gb": 32 + }, + { + "test_name": "memory", + "language": "go", + "data_size": 1024, + "concurrency": 1, + "put_latency_ms": 0, + "get_latency_ms": 0, + "end_to_end_latency_ms": 0, + "ops_per_second": 0, + "bytes_per_second": 0, + "peak_memory_mb": 0.6766204833984375, + "memory_efficiency_ratio": 0.0021530263476599296, + "p50_latency": 0, + "p95_latency": 0, + "p99_latency": 0, + "timestamp": "2025-09-08 17:20:31", + "go_version": "go1.24.4", + "cpu_count": 10, + "total_memory_gb": 32 + }, + { + "test_name": "memory", + "language": "go", + "data_size": 5120, + "concurrency": 1, + "put_latency_ms": 0, + "get_latency_ms": 0, + "end_to_end_latency_ms": 0, + "ops_per_second": 0, + "bytes_per_second": 0, + "peak_memory_mb": 1.20513916015625, + "memory_efficiency_ratio": 0.005618648293686746, + "p50_latency": 0, + "p95_latency": 0, + "p99_latency": 0, + "timestamp": "2025-09-08 17:20:31", + "go_version": "go1.24.4", + "cpu_count": 10, + "total_memory_gb": 32 + }, + { + "test_name": "memory", + "language": "go", + "data_size": 10240, + "concurrency": 1, + "put_latency_ms": 0, + "get_latency_ms": 0, + "end_to_end_latency_ms": 0, + "ops_per_second": 0, + "bytes_per_second": 0, + "peak_memory_mb": 1.9693679809570312, + "memory_efficiency_ratio": 0.007831438084528138, + "p50_latency": 0, + "p95_latency": 0, + "p99_latency": 0, + "timestamp": "2025-09-08 17:20:31", + "go_version": "go1.24.4", + "cpu_count": 10, + "total_memory_gb": 32 + }, + { + "test_name": "memory", + "language": "go", + "data_size": 102400, + "concurrency": 1, + "put_latency_ms": 0, + "get_latency_ms": 0, + "end_to_end_latency_ms": 0, + "ops_per_second": 0, + "bytes_per_second": 0, + "peak_memory_mb": 10.26080322265625, + "memory_efficiency_ratio": 0.016016958655718682, + "p50_latency": 0, + "p95_latency": 0, + "p99_latency": 0, + "timestamp": "2025-09-08 17:20:31", + "go_version": "go1.24.4", + "cpu_count": 10, + "total_memory_gb": 32 + }, + { + "test_name": "memory", + "language": "go", + "data_size": 512000, + "concurrency": 1, + "put_latency_ms": 0, + "get_latency_ms": 0, + "end_to_end_latency_ms": 0, + "ops_per_second": 0, + "bytes_per_second": 0, + "peak_memory_mb": 49.778717041015625, + "memory_efficiency_ratio": 0.01733181410566311, + "p50_latency": 0, + "p95_latency": 0, + "p99_latency": 0, + "timestamp": "2025-09-08 17:20:31", + "go_version": "go1.24.4", + "cpu_count": 10, + "total_memory_gb": 32 + }, + { + "test_name": "memory", + "language": "go", + "data_size": 1048576, + "concurrency": 1, + "put_latency_ms": 0, + "get_latency_ms": 0, + "end_to_end_latency_ms": 0, + "ops_per_second": 0, + "bytes_per_second": 0, + "peak_memory_mb": 102.6750717163086, + "memory_efficiency_ratio": 0.0184339745785116, + "p50_latency": 0, + "p95_latency": 0, + "p99_latency": 0, + "timestamp": "2025-09-08 17:20:31", + "go_version": "go1.24.4", + "cpu_count": 10, + "total_memory_gb": 32 + }, + { + "test_name": "memory", + "language": "go", + "data_size": 10000000, + "concurrency": 1, + "put_latency_ms": 0, + "get_latency_ms": 0, + "end_to_end_latency_ms": 0, + "ops_per_second": 0, + "bytes_per_second": 0, + "peak_memory_mb": 953.8246078491211, + "memory_efficiency_ratio": 0.030570736493434426, + "p50_latency": 0, + "p95_latency": 0, + "p99_latency": 0, + "timestamp": "2025-09-08 17:20:33", + "go_version": "go1.24.4", + "cpu_count": 10, + "total_memory_gb": 32 + }, + { + "test_name": "memory", + "language": "go", + "data_size": 10485760, + "concurrency": 1, + "put_latency_ms": 0, + "get_latency_ms": 0, + "end_to_end_latency_ms": 0, + "ops_per_second": 0, + "bytes_per_second": 0, + "peak_memory_mb": 1000.161262512207, + "memory_efficiency_ratio": 0.03056671376050316, + "p50_latency": 0, + "p95_latency": 0, + "p99_latency": 0, + "timestamp": "2025-09-08 17:20:35", + "go_version": "go1.24.4", + "cpu_count": 10, + "total_memory_gb": 32 + }, + { + "test_name": "memory", + "language": "go", + "data_size": 52428800, + "concurrency": 1, + "put_latency_ms": 0, + "get_latency_ms": 0, + "end_to_end_latency_ms": 0, + "ops_per_second": 0, + "bytes_per_second": 0, + "peak_memory_mb": 5000.225738525391, + "memory_efficiency_ratio": 0.022403277981817665, + "p50_latency": 0, + "p95_latency": 0, + "p99_latency": 0, + "timestamp": "2025-09-08 17:20:46", + "go_version": "go1.24.4", + "cpu_count": 10, + "total_memory_gb": 32 + }, + { + "test_name": "memory", + "language": "go", + "data_size": 104857600, + "concurrency": 1, + "put_latency_ms": 0, + "get_latency_ms": 0, + "end_to_end_latency_ms": 0, + "ops_per_second": 0, + "bytes_per_second": 0, + "peak_memory_mb": 10000.553436279297, + "memory_efficiency_ratio": 0.023714249946008358, + "p50_latency": 0, + "p95_latency": 0, + "p99_latency": 0, + "timestamp": "2025-09-08 17:21:11", + "go_version": "go1.24.4", + "cpu_count": 10, + "total_memory_gb": 32 + }, + { + "test_name": "memory", + "language": "go", + "data_size": 100000000, + "concurrency": 1, + "put_latency_ms": 0, + "get_latency_ms": 0, + "end_to_end_latency_ms": 0, + "ops_per_second": 0, + "bytes_per_second": 0, + "peak_memory_mb": 11278.334442138672, + "memory_efficiency_ratio": 0.02342333662927381, + "p50_latency": 0, + "p95_latency": 0, + "p99_latency": 0, + "timestamp": "2025-09-08 17:21:33", + "go_version": "go1.24.4", + "cpu_count": 10, + "total_memory_gb": 32 + } + ] +} diff --git a/db-esdk-performance-testing/benchmarks/results/raw-data/go_results_released.json b/db-esdk-performance-testing/benchmarks/results/raw-data/go_results_released.json new file mode 100644 index 000000000..e3f9db033 --- /dev/null +++ b/db-esdk-performance-testing/benchmarks/results/raw-data/go_results_released.json @@ -0,0 +1,372 @@ +{ + "metadata": { + "cpu_count": 10, + "go_version": "go1.24.4", + "language": "go", + "timestamp": "2025-09-06 14:52:25", + "total_memory_gb": 32, + "total_tests": 18 + }, + "results": [ + { + "test_name": "throughput", + "language": "go", + "data_size": 1024, + "concurrency": 1, + "put_latency_ms": 1.7174125, + "get_latency_ms": 1.3320956, + "end_to_end_latency_ms": 3.0563126, + "ops_per_second": 323.90106441987297, + "bytes_per_second": 331674.6899659499, + "peak_memory_mb": 0, + "memory_efficiency_ratio": 0, + "p50_latency": 2.104566795, + "p95_latency": 2.1090522105, + "p99_latency": 2.1094509141, + "timestamp": "2025-09-06 14:49:30", + "go_version": "go1.24.4", + "cpu_count": 10, + "total_memory_gb": 32 + }, + { + "test_name": "throughput", + "language": "go", + "data_size": 5120, + "concurrency": 1, + "put_latency_ms": 1.7436083, + "get_latency_ms": 1.3964208, + "end_to_end_latency_ms": 3.1482707, + "ops_per_second": 313.9762574921799, + "bytes_per_second": 1607558.4383599614, + "peak_memory_mb": 0, + "memory_efficiency_ratio": 0, + "p50_latency": 2.263740545, + "p95_latency": 2.2790698354999996, + "p99_latency": 2.2804324391, + "timestamp": "2025-09-06 14:49:30", + "go_version": "go1.24.4", + "cpu_count": 10, + "total_memory_gb": 32 + }, + { + "test_name": "throughput", + "language": "go", + "data_size": 10240, + "concurrency": 1, + "put_latency_ms": 1.8149830999999998, + "get_latency_ms": 1.168129, + "end_to_end_latency_ms": 2.9888413999999996, + "ops_per_second": 331.87080083875696, + "bytes_per_second": 3398357.0005888715, + "peak_memory_mb": 0, + "memory_efficiency_ratio": 0, + "p50_latency": 2.7293562349999996, + "p95_latency": 2.7354143465, + "p99_latency": 2.7359528453, + "timestamp": "2025-09-06 14:49:30", + "go_version": "go1.24.4", + "cpu_count": 10, + "total_memory_gb": 32 + }, + { + "test_name": "throughput", + "language": "go", + "data_size": 102400, + "concurrency": 1, + "put_latency_ms": 4.7371375, + "get_latency_ms": 3.6764208, + "end_to_end_latency_ms": 8.430304099999999, + "ops_per_second": 118.02943949294553, + "bytes_per_second": 12086214.604077622, + "peak_memory_mb": 0, + "memory_efficiency_ratio": 0, + "p50_latency": 7.6777355, + "p95_latency": 7.685410249999999, + "p99_latency": 7.68609245, + "timestamp": "2025-09-06 14:49:30", + "go_version": "go1.24.4", + "cpu_count": 10, + "total_memory_gb": 32 + }, + { + "test_name": "throughput", + "language": "go", + "data_size": 512000, + "concurrency": 1, + "put_latency_ms": 18.841974800000003, + "get_latency_ms": 10.8928624, + "end_to_end_latency_ms": 29.7788748, + "ops_per_second": 33.5067259491787, + "bytes_per_second": 17155443.685979493, + "peak_memory_mb": 0, + "memory_efficiency_ratio": 0, + "p50_latency": 24.715475, + "p95_latency": 24.721752499999997, + "p99_latency": 24.722310500000003, + "timestamp": "2025-09-06 14:49:31", + "go_version": "go1.24.4", + "cpu_count": 10, + "total_memory_gb": 32 + }, + { + "test_name": "throughput", + "language": "go", + "data_size": 1048576, + "concurrency": 1, + "put_latency_ms": 30.499370799999998, + "get_latency_ms": 23.271137600000003, + "end_to_end_latency_ms": 53.82045839999999, + "ops_per_second": 18.561928510124485, + "bytes_per_second": 19463592.74943229, + "peak_memory_mb": 0, + "memory_efficiency_ratio": 0, + "p50_latency": 45.853811279999995, + "p95_latency": 45.935766432, + "p99_latency": 45.943051334399996, + "timestamp": "2025-09-06 14:49:31", + "go_version": "go1.24.4", + "cpu_count": 10, + "total_memory_gb": 32 + }, + { + "test_name": "throughput", + "language": "go", + "data_size": 10485760, + "concurrency": 1, + "put_latency_ms": 284.17867079999996, + "get_latency_ms": 188.6229376, + "end_to_end_latency_ms": 473.1885916000001, + "ops_per_second": 2.113069801747077, + "bytes_per_second": 22157142.804367427, + "peak_memory_mb": 0, + "memory_efficiency_ratio": 0, + "p50_latency": 364.388903515, + "p95_latency": 364.43017977849996, + "p99_latency": 364.4338487797, + "timestamp": "2025-09-06 14:49:39", + "go_version": "go1.24.4", + "cpu_count": 10, + "total_memory_gb": 32 + }, + { + "test_name": "throughput", + "language": "go", + "data_size": 52428800, + "concurrency": 1, + "put_latency_ms": 1436.6804917, + "get_latency_ms": 853.1655126000002, + "end_to_end_latency_ms": 2291.8107959, + "ops_per_second": 0.436324417138726, + "bytes_per_second": 22875965.60128284, + "peak_memory_mb": 0, + "memory_efficiency_ratio": 0, + "p50_latency": 1723.097458, + "p95_latency": 1726.0073830000001, + "p99_latency": 1726.266043, + "timestamp": "2025-09-06 14:50:13", + "go_version": "go1.24.4", + "cpu_count": 10, + "total_memory_gb": 32 + }, + { + "test_name": "throughput", + "language": "go", + "data_size": 104857600, + "concurrency": 1, + "put_latency_ms": 3284.883158400001, + "get_latency_ms": 2420.3637873999996, + "end_to_end_latency_ms": 5728.687533400001, + "ops_per_second": 0.17455816568065233, + "bytes_per_second": 18303750.313675568, + "peak_memory_mb": 0, + "memory_efficiency_ratio": 0, + "p50_latency": 4542.684611219999, + "p95_latency": 4579.399761317999, + "p99_latency": 4582.6633302156, + "timestamp": "2025-09-06 14:51:42", + "go_version": "go1.24.4", + "cpu_count": 10, + "total_memory_gb": 32 + }, + { + "test_name": "memory", + "language": "go", + "data_size": 1024, + "concurrency": 1, + "put_latency_ms": 0, + "get_latency_ms": 0, + "end_to_end_latency_ms": 0, + "ops_per_second": 0, + "bytes_per_second": 0, + "peak_memory_mb": 0.6713943481445312, + "memory_efficiency_ratio": 0.0021415712440521206, + "p50_latency": 0, + "p95_latency": 0, + "p99_latency": 0, + "timestamp": "2025-09-06 14:51:42", + "go_version": "go1.24.4", + "cpu_count": 10, + "total_memory_gb": 32 + }, + { + "test_name": "memory", + "language": "go", + "data_size": 5120, + "concurrency": 1, + "put_latency_ms": 0, + "get_latency_ms": 0, + "end_to_end_latency_ms": 0, + "ops_per_second": 0, + "bytes_per_second": 0, + "peak_memory_mb": 1.2037811279296875, + "memory_efficiency_ratio": 0.005625819699510906, + "p50_latency": 0, + "p95_latency": 0, + "p99_latency": 0, + "timestamp": "2025-09-06 14:51:42", + "go_version": "go1.24.4", + "cpu_count": 10, + "total_memory_gb": 32 + }, + { + "test_name": "memory", + "language": "go", + "data_size": 10240, + "concurrency": 1, + "put_latency_ms": 0, + "get_latency_ms": 0, + "end_to_end_latency_ms": 0, + "ops_per_second": 0, + "bytes_per_second": 0, + "peak_memory_mb": 1.7346038818359375, + "memory_efficiency_ratio": 0.007804173769684199, + "p50_latency": 0, + "p95_latency": 0, + "p99_latency": 0, + "timestamp": "2025-09-06 14:51:42", + "go_version": "go1.24.4", + "cpu_count": 10, + "total_memory_gb": 32 + }, + { + "test_name": "memory", + "language": "go", + "data_size": 102400, + "concurrency": 1, + "put_latency_ms": 0, + "get_latency_ms": 0, + "end_to_end_latency_ms": 0, + "ops_per_second": 0, + "bytes_per_second": 0, + "peak_memory_mb": 10.267852783203125, + "memory_efficiency_ratio": 0.016467955210732743, + "p50_latency": 0, + "p95_latency": 0, + "p99_latency": 0, + "timestamp": "2025-09-06 14:51:42", + "go_version": "go1.24.4", + "cpu_count": 10, + "total_memory_gb": 32 + }, + { + "test_name": "memory", + "language": "go", + "data_size": 512000, + "concurrency": 1, + "put_latency_ms": 0, + "get_latency_ms": 0, + "end_to_end_latency_ms": 0, + "ops_per_second": 0, + "bytes_per_second": 0, + "peak_memory_mb": 50.350738525390625, + "memory_efficiency_ratio": 0.01711402452553535, + "p50_latency": 0, + "p95_latency": 0, + "p99_latency": 0, + "timestamp": "2025-09-06 14:51:43", + "go_version": "go1.24.4", + "cpu_count": 10, + "total_memory_gb": 32 + }, + { + "test_name": "memory", + "language": "go", + "data_size": 1048576, + "concurrency": 1, + "put_latency_ms": 0, + "get_latency_ms": 0, + "end_to_end_latency_ms": 0, + "ops_per_second": 0, + "bytes_per_second": 0, + "peak_memory_mb": 102.61759948730469, + "memory_efficiency_ratio": 0.017131056275642438, + "p50_latency": 0, + "p95_latency": 0, + "p99_latency": 0, + "timestamp": "2025-09-06 14:51:43", + "go_version": "go1.24.4", + "cpu_count": 10, + "total_memory_gb": 32 + }, + { + "test_name": "memory", + "language": "go", + "data_size": 10485760, + "concurrency": 1, + "put_latency_ms": 0, + "get_latency_ms": 0, + "end_to_end_latency_ms": 0, + "ops_per_second": 0, + "bytes_per_second": 0, + "peak_memory_mb": 1000.1706314086914, + "memory_efficiency_ratio": 0.03033901317413952, + "p50_latency": 0, + "p95_latency": 0, + "p99_latency": 0, + "timestamp": "2025-09-06 14:51:45", + "go_version": "go1.24.4", + "cpu_count": 10, + "total_memory_gb": 32 + }, + { + "test_name": "memory", + "language": "go", + "data_size": 52428800, + "concurrency": 1, + "put_latency_ms": 0, + "get_latency_ms": 0, + "end_to_end_latency_ms": 0, + "ops_per_second": 0, + "bytes_per_second": 0, + "peak_memory_mb": 5000.346694946289, + "memory_efficiency_ratio": 0.02773221478826035, + "p50_latency": 0, + "p95_latency": 0, + "p99_latency": 0, + "timestamp": "2025-09-06 14:51:55", + "go_version": "go1.24.4", + "cpu_count": 10, + "total_memory_gb": 32 + }, + { + "test_name": "memory", + "language": "go", + "data_size": 104857600, + "concurrency": 1, + "put_latency_ms": 0, + "get_latency_ms": 0, + "end_to_end_latency_ms": 0, + "ops_per_second": 0, + "bytes_per_second": 0, + "peak_memory_mb": 10000.726448059082, + "memory_efficiency_ratio": 0.022509158228733804, + "p50_latency": 0, + "p95_latency": 0, + "p99_latency": 0, + "timestamp": "2025-09-06 14:52:25", + "go_version": "go1.24.4", + "cpu_count": 10, + "total_memory_gb": 32 + } + ] +} diff --git a/db-esdk-performance-testing/benchmarks/results/raw-data/go_results_robinPR.json b/db-esdk-performance-testing/benchmarks/results/raw-data/go_results_robinPR.json new file mode 100644 index 000000000..fefc16d98 --- /dev/null +++ b/db-esdk-performance-testing/benchmarks/results/raw-data/go_results_robinPR.json @@ -0,0 +1,372 @@ +{ + "metadata": { + "cpu_count": 10, + "go_version": "go1.24.4", + "language": "go", + "timestamp": "2025-09-06 15:02:42", + "total_memory_gb": 32, + "total_tests": 18 + }, + "results": [ + { + "test_name": "throughput", + "language": "go", + "data_size": 1024, + "concurrency": 1, + "put_latency_ms": 1.5847793, + "get_latency_ms": 1.3858458999999999, + "end_to_end_latency_ms": 2.976754, + "ops_per_second": 332.4873414588141, + "bytes_per_second": 340467.03765382565, + "peak_memory_mb": 0, + "memory_efficiency_ratio": 0, + "p50_latency": 2.2945317499999995, + "p95_latency": 2.307198125, + "p99_latency": 2.308324025, + "timestamp": "2025-09-06 14:58:26", + "go_version": "go1.24.4", + "cpu_count": 10, + "total_memory_gb": 32 + }, + { + "test_name": "throughput", + "language": "go", + "data_size": 5120, + "concurrency": 1, + "put_latency_ms": 1.4361586, + "get_latency_ms": 1.6419501, + "end_to_end_latency_ms": 3.0856667, + "ops_per_second": 321.1471375754194, + "bytes_per_second": 1644273.3443861473, + "peak_memory_mb": 0, + "memory_efficiency_ratio": 0, + "p50_latency": 2.76639178, + "p95_latency": 2.773644682, + "p99_latency": 2.7742893844000003, + "timestamp": "2025-09-06 14:58:26", + "go_version": "go1.24.4", + "cpu_count": 10, + "total_memory_gb": 32 + }, + { + "test_name": "throughput", + "language": "go", + "data_size": 10240, + "concurrency": 1, + "put_latency_ms": 1.8749458000000003, + "get_latency_ms": 1.744075, + "end_to_end_latency_ms": 3.6273876, + "ops_per_second": 272.53402628198234, + "bytes_per_second": 2790748.4291274995, + "peak_memory_mb": 0, + "memory_efficiency_ratio": 0, + "p50_latency": 3.2027300949999997, + "p95_latency": 3.2063868804999998, + "p99_latency": 3.2067119281000003, + "timestamp": "2025-09-06 14:58:27", + "go_version": "go1.24.4", + "cpu_count": 10, + "total_memory_gb": 32 + }, + { + "test_name": "throughput", + "language": "go", + "data_size": 102400, + "concurrency": 1, + "put_latency_ms": 6.4893667, + "get_latency_ms": 4.30905, + "end_to_end_latency_ms": 10.811225099999998, + "ops_per_second": 92.17166847900747, + "bytes_per_second": 9438378.852250364, + "peak_memory_mb": 0, + "memory_efficiency_ratio": 0, + "p50_latency": 10.389003124999999, + "p95_latency": 10.3942934375, + "p99_latency": 10.394763687500001, + "timestamp": "2025-09-06 14:58:27", + "go_version": "go1.24.4", + "cpu_count": 10, + "total_memory_gb": 32 + }, + { + "test_name": "throughput", + "language": "go", + "data_size": 512000, + "concurrency": 1, + "put_latency_ms": 23.9508043, + "get_latency_ms": 15.7898875, + "end_to_end_latency_ms": 39.764225, + "ops_per_second": 25.120384228937453, + "bytes_per_second": 12861636.725215977, + "peak_memory_mb": 0, + "memory_efficiency_ratio": 0, + "p50_latency": 37.95913253, + "p95_latency": 38.003351807, + "p99_latency": 38.0072824094, + "timestamp": "2025-09-06 14:58:27", + "go_version": "go1.24.4", + "cpu_count": 10, + "total_memory_gb": 32 + }, + { + "test_name": "throughput", + "language": "go", + "data_size": 1048576, + "concurrency": 1, + "put_latency_ms": 47.535987399999996, + "get_latency_ms": 30.3682291, + "end_to_end_latency_ms": 77.9412166, + "ops_per_second": 12.82240741340307, + "bytes_per_second": 13445268.675916538, + "peak_memory_mb": 0, + "memory_efficiency_ratio": 0, + "p50_latency": 77.17696417, + "p95_latency": 77.186345023, + "p99_latency": 77.18717887660002, + "timestamp": "2025-09-06 14:58:28", + "go_version": "go1.24.4", + "cpu_count": 10, + "total_memory_gb": 32 + }, + { + "test_name": "throughput", + "language": "go", + "data_size": 10485760, + "concurrency": 1, + "put_latency_ms": 427.26489979999997, + "get_latency_ms": 265.07672489999993, + "end_to_end_latency_ms": 692.7832958000001, + "ops_per_second": 1.4433298109470685, + "bytes_per_second": 15134409.998436332, + "peak_memory_mb": 0, + "memory_efficiency_ratio": 0, + "p50_latency": 682.9184412799999, + "p95_latency": 683.007038432, + "p99_latency": 683.0149137344, + "timestamp": "2025-09-06 14:58:39", + "go_version": "go1.24.4", + "cpu_count": 10, + "total_memory_gb": 32 + }, + { + "test_name": "throughput", + "language": "go", + "data_size": 52428800, + "concurrency": 1, + "put_latency_ms": 2112.4756165999997, + "get_latency_ms": 1321.6268916, + "end_to_end_latency_ms": 3436.0430752, + "ops_per_second": 0.2910274046610411, + "bytes_per_second": 15258217.593492791, + "peak_memory_mb": 0, + "memory_efficiency_ratio": 0, + "p50_latency": 3408.2480412349996, + "p95_latency": 3408.3905033465, + "p99_latency": 3408.4031666452997, + "timestamp": "2025-09-06 14:59:32", + "go_version": "go1.24.4", + "cpu_count": 10, + "total_memory_gb": 32 + }, + { + "test_name": "throughput", + "language": "go", + "data_size": 104857600, + "concurrency": 1, + "put_latency_ms": 5590.5194667999995, + "get_latency_ms": 3161.9229500999995, + "end_to_end_latency_ms": 8776.9374624, + "ops_per_second": 0.1139341495256053, + "bytes_per_second": 11946861.477296108, + "peak_memory_mb": 0, + "memory_efficiency_ratio": 0, + "p50_latency": 8563.84046247, + "p95_latency": 8567.610978693, + "p99_latency": 8567.9461356906, + "timestamp": "2025-09-06 15:01:43", + "go_version": "go1.24.4", + "cpu_count": 10, + "total_memory_gb": 32 + }, + { + "test_name": "memory", + "language": "go", + "data_size": 1024, + "concurrency": 1, + "put_latency_ms": 0, + "get_latency_ms": 0, + "end_to_end_latency_ms": 0, + "ops_per_second": 0, + "bytes_per_second": 0, + "peak_memory_mb": 1.162567138671875, + "memory_efficiency_ratio": 0.0012987838783039506, + "p50_latency": 0, + "p95_latency": 0, + "p99_latency": 0, + "timestamp": "2025-09-06 15:01:43", + "go_version": "go1.24.4", + "cpu_count": 10, + "total_memory_gb": 32 + }, + { + "test_name": "memory", + "language": "go", + "data_size": 5120, + "concurrency": 1, + "put_latency_ms": 0, + "get_latency_ms": 0, + "end_to_end_latency_ms": 0, + "ops_per_second": 0, + "bytes_per_second": 0, + "peak_memory_mb": 1.7072677612304688, + "memory_efficiency_ratio": 0.004336758318331612, + "p50_latency": 0, + "p95_latency": 0, + "p99_latency": 0, + "timestamp": "2025-09-06 15:01:43", + "go_version": "go1.24.4", + "cpu_count": 10, + "total_memory_gb": 32 + }, + { + "test_name": "memory", + "language": "go", + "data_size": 10240, + "concurrency": 1, + "put_latency_ms": 0, + "get_latency_ms": 0, + "end_to_end_latency_ms": 0, + "ops_per_second": 0, + "bytes_per_second": 0, + "peak_memory_mb": 2.079681396484375, + "memory_efficiency_ratio": 0.00665892566558043, + "p50_latency": 0, + "p95_latency": 0, + "p99_latency": 0, + "timestamp": "2025-09-06 15:01:43", + "go_version": "go1.24.4", + "cpu_count": 10, + "total_memory_gb": 32 + }, + { + "test_name": "memory", + "language": "go", + "data_size": 102400, + "concurrency": 1, + "put_latency_ms": 0, + "get_latency_ms": 0, + "end_to_end_latency_ms": 0, + "ops_per_second": 0, + "bytes_per_second": 0, + "peak_memory_mb": 7.1639251708984375, + "memory_efficiency_ratio": 0.02116934701805992, + "p50_latency": 0, + "p95_latency": 0, + "p99_latency": 0, + "timestamp": "2025-09-06 15:01:43", + "go_version": "go1.24.4", + "cpu_count": 10, + "total_memory_gb": 32 + }, + { + "test_name": "memory", + "language": "go", + "data_size": 512000, + "concurrency": 1, + "put_latency_ms": 0, + "get_latency_ms": 0, + "end_to_end_latency_ms": 0, + "ops_per_second": 0, + "bytes_per_second": 0, + "peak_memory_mb": 41.20851135253906, + "memory_efficiency_ratio": 0.024750771165236052, + "p50_latency": 0, + "p95_latency": 0, + "p99_latency": 0, + "timestamp": "2025-09-06 15:01:43", + "go_version": "go1.24.4", + "cpu_count": 10, + "total_memory_gb": 32 + }, + { + "test_name": "memory", + "language": "go", + "data_size": 1048576, + "concurrency": 1, + "put_latency_ms": 0, + "get_latency_ms": 0, + "end_to_end_latency_ms": 0, + "ops_per_second": 0, + "bytes_per_second": 0, + "peak_memory_mb": 68.15657806396484, + "memory_efficiency_ratio": 0.025135704105513763, + "p50_latency": 0, + "p95_latency": 0, + "p99_latency": 0, + "timestamp": "2025-09-06 15:01:44", + "go_version": "go1.24.4", + "cpu_count": 10, + "total_memory_gb": 32 + }, + { + "test_name": "memory", + "language": "go", + "data_size": 10485760, + "concurrency": 1, + "put_latency_ms": 0, + "get_latency_ms": 0, + "end_to_end_latency_ms": 0, + "ops_per_second": 0, + "bytes_per_second": 0, + "peak_memory_mb": 680.1585235595703, + "memory_efficiency_ratio": 0.025431506916729883, + "p50_latency": 0, + "p95_latency": 0, + "p99_latency": 0, + "timestamp": "2025-09-06 15:01:47", + "go_version": "go1.24.4", + "cpu_count": 10, + "total_memory_gb": 32 + }, + { + "test_name": "memory", + "language": "go", + "dataSize":52428800, + "concurrency": 1, + "put_latency_ms": 0, + "get_latency_ms": 0, + "end_to_end_latency_ms": 0, + "ops_per_second": 0, + "bytes_per_second": 0, + "peak_memory_mb": 3400.3147354125977, + "memory_efficiency_ratio": 0.024740892611872345, + "p50_latency": 0, + "p95_latency": 0, + "p99_latency": 0, + "timestamp": "2025-09-06 15:02:05", + "go_version": "go1.24.4", + "cpu_count": 10, + "total_memory_gb": 32 + }, + { + "test_name": "memory", + "language": "go", + "data_size": 104857600, + "concurrency": 1, + "put_latency_ms": 0, + "get_latency_ms": 0, + "end_to_end_latency_ms": 0, + "ops_per_second": 0, + "bytes_per_second": 0, + "peak_memory_mb": 6800.700630187988, + "memory_efficiency_ratio": 0.02486452301293448, + "p50_latency": 0, + "p95_latency": 0, + "p99_latency": 0, + "timestamp": "2025-09-06 15:02:42", + "go_version": "go1.24.4", + "cpu_count": 10, + "total_memory_gb": 32 + } + ] +}