From 76aac2c0473777eeb6a819d5a621c41793b44710 Mon Sep 17 00:00:00 2001 From: rishav-karanjit Date: Wed, 3 Sep 2025 21:11:36 -0700 Subject: [PATCH 01/33] auto commit --- db-esdk-performance-testing/go/README.md | 45 ++ .../go/benchmark/benchmark_tests.go | 474 ++++++++++++++++++ .../go/benchmark/config.go | 60 +++ .../go/benchmark/esdk_benchmark.go | 163 ++++++ .../go/benchmark/results.go | 117 +++++ .../go/config/test-scenarios.yaml | 38 ++ db-esdk-performance-testing/go/go.mod | 51 ++ db-esdk-performance-testing/go/go.sum | 105 ++++ db-esdk-performance-testing/go/main.go | 104 ++++ 9 files changed, 1157 insertions(+) create mode 100644 db-esdk-performance-testing/go/README.md create mode 100644 db-esdk-performance-testing/go/benchmark/benchmark_tests.go create mode 100644 db-esdk-performance-testing/go/benchmark/config.go create mode 100644 db-esdk-performance-testing/go/benchmark/esdk_benchmark.go create mode 100644 db-esdk-performance-testing/go/benchmark/results.go create mode 100644 db-esdk-performance-testing/go/config/test-scenarios.yaml create mode 100644 db-esdk-performance-testing/go/go.mod create mode 100644 db-esdk-performance-testing/go/go.sum create mode 100644 db-esdk-performance-testing/go/main.go diff --git a/db-esdk-performance-testing/go/README.md b/db-esdk-performance-testing/go/README.md new file mode 100644 index 000000000..0d69f41d8 --- /dev/null +++ b/db-esdk-performance-testing/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/go/benchmark/benchmark_tests.go b/db-esdk-performance-testing/go/benchmark/benchmark_tests.go new file mode 100644 index 000000000..8f34117a7 --- /dev/null +++ b/db-esdk-performance-testing/go/benchmark/benchmark_tests.go @@ -0,0 +1,474 @@ +// Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. +// SPDX-License-Identifier: Apache-2.0 + +package benchmark + +import ( + "context" + "fmt" + "log" + "runtime" + "runtime/metrics" + "sort" + "sync" + "time" + + "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" + "github.com/schollz/progressbar/v3" +) + +// === Helper Functions === + +// runPutGetCycle performs a single PutItem-GetItem cycle and measures performance +func (b *DBESDKBenchmark) runPutGetCycle(data []byte, itemId string) (float64, float64, error) { + ctx := context.Background() + tableName := b.Config.TableName + + // Create DynamoDB item with test data + item := map[string]types.AttributeValue{ + "partition_key": &types.AttributeValueMemberS{Value: "benchmark-test"}, + "sort_key": &types.AttributeValueMemberN{Value: itemId}, + "attribute1": &types.AttributeValueMemberB{Value: data}, // Store test data as binary + "attribute2": &types.AttributeValueMemberS{Value: "sign me!"}, + ":attribute3": &types.AttributeValueMemberS{Value: "ignore me!"}, + } + + // PutItem + putStart := time.Now() + putInput := &dynamodb.PutItemInput{ + TableName: aws.String(tableName), + Item: item, + } + _, err := b.DbesdkClient.PutItem(ctx, putInput) + if err != nil { + return 0, 0, fmt.Errorf("PutItem failed: %w", err) + } + putDuration := time.Since(putStart).Seconds() * 1000 + + // GetItem + key := map[string]types.AttributeValue{ + "partition_key": &types.AttributeValueMemberS{Value: "benchmark-test"}, + "sort_key": &types.AttributeValueMemberN{Value: itemId}, + } + + getStart := time.Now() + getInput := &dynamodb.GetItemInput{ + TableName: aws.String(tableName), + Key: key, + ConsistentRead: aws.Bool(true), + } + result, err := b.DbesdkClient.GetItem(ctx, getInput) + if err != nil { + return 0, 0, fmt.Errorf("GetItem failed: %w", err) + } + getDuration := time.Since(getStart).Seconds() * 1000 + + // Verify data integrity + if result.Item == nil { + return 0, 0, fmt.Errorf("item not found") + } + + retrievedData, ok := result.Item["attribute1"].(*types.AttributeValueMemberB) + if !ok { + return 0, 0, fmt.Errorf("attribute1 not found or wrong type") + } + + if len(retrievedData.Value) != len(data) { + return 0, 0, fmt.Errorf("data size mismatch: expected %d, got %d", len(data), len(retrievedData.Value)) + } + + return putDuration, getDuration, 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 +} + +// === 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++ { + itemId := fmt.Sprintf("%d", i) // Use numeric string for Number attribute + if _, _, err := b.runPutGetCycle(testData, itemId); 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++ { + itemId := fmt.Sprintf("%d", 1000+i) // Use numeric string, offset to avoid warmup conflicts + iterationStart := time.Now() + putMs, getMs, err := b.runPutGetCycle(testData, itemId) + 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 +} + +// === 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) + } + } +} + +// 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) + + // Get baseline + metrics.Read(samples) + beforeHeap := samples[0].Value.Uint64() + beforeAllocs := samples[1].Value.Uint64() + + // Start continuous sampling + stopSampling := make(chan bool) + var continuousSamples []MemorySample + var samplingMutex sync.Mutex + + go func() { + sampledData := b.sampleMemoryContinuously(beforeHeap, beforeAllocs, stopSampling) + samplingMutex.Lock() + continuousSamples = sampledData + samplingMutex.Unlock() + }() + + // Run operation + operationStart := time.Now() + itemId := fmt.Sprintf("%d", 2000+i) // Use numeric string, offset to avoid conflicts + _, _, err := b.runPutGetCycle(data, itemId) + 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.runEncryptDecryptCycle(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 +// } + +// === 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 +} diff --git a/db-esdk-performance-testing/go/benchmark/config.go b/db-esdk-performance-testing/go/benchmark/config.go new file mode 100644 index 000000000..46bfb08dd --- /dev/null +++ b/db-esdk-performance-testing/go/benchmark/config.go @@ -0,0 +1,60 @@ +// 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" +) + +// 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"` +} + +// 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/go/benchmark/esdk_benchmark.go b/db-esdk-performance-testing/go/benchmark/esdk_benchmark.go new file mode 100644 index 000000000..4e7dd7177 --- /dev/null +++ b/db-esdk-performance-testing/go/benchmark/esdk_benchmark.go @@ -0,0 +1,163 @@ +// 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" + 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 + 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 DB-ESDK + if err := benchmark.setupDBESDK(); 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 +} + +// setupDBESDK initializes the DynamoDB client with DB-ESDK middleware and creates a default keyring which is AES keyring +func (b *DBESDKBenchmark) setupDBESDK() error { + ddbTableName := b.Config.TableName + + // 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) + } + + // Create default AES-256 keyring + key := make([]byte, 32) // 256-bit key + if _, err := rand.Read(key); err != nil { + return 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 fmt.Errorf("failed to create keyring: %w", err) + } + b.Keyring = keyring + + 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 + tableConfig := dbesdkdynamodbencryptiontypes.DynamoDbTableEncryptionConfig{ + LogicalTableName: ddbTableName, + PartitionKeyName: partitionKey, + SortKeyName: &sortKeyName, + AttributeActionsOnEncrypt: attributeActions, + Keyring: keyring, + AllowedUnsignedAttributePrefix: &allowedUnsignedAttributePrefix, + AlgorithmSuiteId: &algorithmSuiteID, + } + tableConfigsMap := make(map[string]dbesdkdynamodbencryptiontypes.DynamoDbTableEncryptionConfig) + tableConfigsMap[ddbTableName] = tableConfig + listOfTableConfigs := dbesdkdynamodbencryptiontypes.DynamoDbTablesEncryptionConfig{ + TableEncryptionConfigs: tableConfigsMap, + } + + cfg, err := config.LoadDefaultConfig(context.TODO()) + + dbEsdkMiddleware, err := dbesdkmiddleware.NewDBEsdkMiddleware(listOfTableConfigs) + ddb := dynamodb.NewFromConfig(cfg, dbEsdkMiddleware.CreateMiddleware(), func(o *dynamodb.Options) { + o.EndpointResolverV2 = &resolverV2{} + }) + + b.DbesdkClient = ddb + + log.Println("ESDK client initialized successfully") + 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/go/benchmark/results.go b/db-esdk-performance-testing/go/benchmark/results.go new file mode 100644 index 000000000..c71e2ad98 --- /dev/null +++ b/db-esdk-performance-testing/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/go/config/test-scenarios.yaml b/db-esdk-performance-testing/go/config/test-scenarios.yaml new file mode 100644 index 000000000..9464a979b --- /dev/null +++ b/db-esdk-performance-testing/go/config/test-scenarios.yaml @@ -0,0 +1,38 @@ +# 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: + medium: + - 400 # 400KB + +# 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 + +table_name: "dbesdk-performance-testing" # DynamoDB table name diff --git a/db-esdk-performance-testing/go/go.mod b/db-esdk-performance-testing/go/go.mod new file mode 100644 index 000000000..85a94a38a --- /dev/null +++ b/db-esdk-performance-testing/go/go.mod @@ -0,0 +1,51 @@ +module github.com/aws/aws-encryption-sdk/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-encryption-sdk/releases/go/encryption-sdk v0.2.0 + 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/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 v1.38.1 // 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/aws/smithy-go v1.22.5 // 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/go/go.sum b/db-esdk-performance-testing/go/go.sum new file mode 100644 index 000000000..3b287bdb0 --- /dev/null +++ b/db-esdk-performance-testing/go/go.sum @@ -0,0 +1,105 @@ +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-encryption-sdk/releases/go/encryption-sdk v0.2.0 h1:WD+Zmu/WR3rW8u1qfuKH1T10SXQPAb/Dtv+lRceAqzQ= +github.com/aws/aws-encryption-sdk/releases/go/encryption-sdk v0.2.0/go.mod h1:dZucPyqttfAV6EEYohPSB8ZkF8yBqCiSltsK1Joa/Sg= +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/go/main.go b/db-esdk-performance-testing/go/main.go new file mode 100644 index 000000000..ffd21f99a --- /dev/null +++ b/db-esdk-performance-testing/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-encryption-sdk/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 +} From 3746e6d3d1388ff8e7292fc309d48596b4691fc4 Mon Sep 17 00:00:00 2001 From: rishav-karanjit Date: Wed, 3 Sep 2025 21:14:48 -0700 Subject: [PATCH 02/33] auto commit --- .../go/benchmark/{esdk_benchmark.go => dbesdk_benchmark.go} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename db-esdk-performance-testing/go/benchmark/{esdk_benchmark.go => dbesdk_benchmark.go} (100%) diff --git a/db-esdk-performance-testing/go/benchmark/esdk_benchmark.go b/db-esdk-performance-testing/go/benchmark/dbesdk_benchmark.go similarity index 100% rename from db-esdk-performance-testing/go/benchmark/esdk_benchmark.go rename to db-esdk-performance-testing/go/benchmark/dbesdk_benchmark.go From 16fa9e594c213025f2c6f0ef5ad2ab8714c4da2b Mon Sep 17 00:00:00 2001 From: rishav-karanjit Date: Wed, 3 Sep 2025 21:57:22 -0700 Subject: [PATCH 03/33] remove put get and add batch put get --- .../go/benchmark/benchmark_tests.go | 99 ++++++++++--------- 1 file changed, 53 insertions(+), 46 deletions(-) diff --git a/db-esdk-performance-testing/go/benchmark/benchmark_tests.go b/db-esdk-performance-testing/go/benchmark/benchmark_tests.go index 8f34117a7..d8c379c2a 100644 --- a/db-esdk-performance-testing/go/benchmark/benchmark_tests.go +++ b/db-esdk-performance-testing/go/benchmark/benchmark_tests.go @@ -10,6 +10,7 @@ import ( "runtime" "runtime/metrics" "sort" + "strconv" "sync" "time" @@ -21,65 +22,71 @@ import ( // === Helper Functions === -// runPutGetCycle performs a single PutItem-GetItem cycle and measures performance -func (b *DBESDKBenchmark) runPutGetCycle(data []byte, itemId string) (float64, float64, error) { +// runBatchPutGetCycle performs a BatchWriteItem-BatchGetItem cycle with 25 items and measures performance +func (b *DBESDKBenchmark) runBatchPutGetCycle(data []byte, baseItemId string) (float64, float64, error) { ctx := context.Background() tableName := b.Config.TableName - // Create DynamoDB item with test data - item := map[string]types.AttributeValue{ - "partition_key": &types.AttributeValueMemberS{Value: "benchmark-test"}, - "sort_key": &types.AttributeValueMemberN{Value: itemId}, - "attribute1": &types.AttributeValueMemberB{Value: data}, // Store test data as binary - "attribute2": &types.AttributeValueMemberS{Value: "sign me!"}, - ":attribute3": &types.AttributeValueMemberS{Value: "ignore me!"}, + // Create 25 write requests with same data, different sort_key + var writeRequests []types.WriteRequest + for i := 0; i < 25; i++ { + item := map[string]types.AttributeValue{ + "partition_key": &types.AttributeValueMemberS{Value: "benchmark-test"}, + "sort_key": &types.AttributeValueMemberN{Value: strconv.Itoa(i)}, + "attribute1": &types.AttributeValueMemberB{Value: data}, + "attribute2": &types.AttributeValueMemberS{Value: "sign me!"}, + ":attribute3": &types.AttributeValueMemberS{Value: "ignore me!"}, + } + writeRequests = append(writeRequests, types.WriteRequest{ + PutRequest: &types.PutRequest{Item: item}, + }) } - // PutItem - putStart := time.Now() - putInput := &dynamodb.PutItemInput{ - TableName: aws.String(tableName), - Item: item, - } - _, err := b.DbesdkClient.PutItem(ctx, putInput) + // BatchWriteItem + batchWriteStart := time.Now() + _, err := b.DbesdkClient.BatchWriteItem(ctx, &dynamodb.BatchWriteItemInput{ + RequestItems: map[string][]types.WriteRequest{tableName: writeRequests}, + }) if err != nil { - return 0, 0, fmt.Errorf("PutItem failed: %w", err) + return 0, 0, fmt.Errorf("BatchWriteItem failed: %w", err) } - putDuration := time.Since(putStart).Seconds() * 1000 - - // GetItem - key := map[string]types.AttributeValue{ - "partition_key": &types.AttributeValueMemberS{Value: "benchmark-test"}, - "sort_key": &types.AttributeValueMemberN{Value: itemId}, + batchWriteDuration := time.Since(batchWriteStart).Seconds() * 1000 + + // Create 25 keys for BatchGetItem + var keys []map[string]types.AttributeValue + for i := 0; i < 25; i++ { + keys = append(keys, map[string]types.AttributeValue{ + "partition_key": &types.AttributeValueMemberS{Value: "benchmark-test"}, + "sort_key": &types.AttributeValueMemberN{Value: strconv.Itoa(i)}, + }) } - getStart := time.Now() - getInput := &dynamodb.GetItemInput{ - TableName: aws.String(tableName), - Key: key, - ConsistentRead: aws.Bool(true), - } - result, err := b.DbesdkClient.GetItem(ctx, getInput) + // BatchGetItem + batchGetStart := time.Now() + result, err := b.DbesdkClient.BatchGetItem(ctx, &dynamodb.BatchGetItemInput{ + RequestItems: map[string]types.KeysAndAttributes{ + tableName: {Keys: keys, ConsistentRead: aws.Bool(true)}, + }, + }) if err != nil { - return 0, 0, fmt.Errorf("GetItem failed: %w", err) + return 0, 0, fmt.Errorf("BatchGetItem failed: %w", err) } - getDuration := time.Since(getStart).Seconds() * 1000 + batchGetDuration := time.Since(batchGetStart).Seconds() * 1000 - // Verify data integrity - if result.Item == nil { - return 0, 0, fmt.Errorf("item not found") + // Verify 25 items retrieved with correct data size + items := result.Responses[tableName] + if len(items) != 25 { + return 0, 0, fmt.Errorf("expected 25 items, got %d", len(items)) } - retrievedData, ok := result.Item["attribute1"].(*types.AttributeValueMemberB) - if !ok { - return 0, 0, fmt.Errorf("attribute1 not found or wrong type") - } - - if len(retrievedData.Value) != len(data) { - return 0, 0, fmt.Errorf("data size mismatch: expected %d, got %d", len(data), len(retrievedData.Value)) + for _, item := range items { + retrievedData, ok := item["attribute1"].(*types.AttributeValueMemberB) + if !ok || len(retrievedData.Value) != len(data) { + return 0, 0, fmt.Errorf("data verification failed") + } } - return putDuration, getDuration, nil + return batchWriteDuration, batchGetDuration, nil } // shouldRunTestType checks if a test type should be run based on quick config @@ -107,7 +114,7 @@ func (b *DBESDKBenchmark) runThroughputTest(dataSize int, iterations int) (*Benc // Warmup for i := 0; i < b.Config.Iterations.Warmup; i++ { itemId := fmt.Sprintf("%d", i) // Use numeric string for Number attribute - if _, _, err := b.runPutGetCycle(testData, itemId); err != nil { + if _, _, err := b.runBatchPutGetCycle(testData, itemId); err != nil { return nil, fmt.Errorf("warmup iteration %d failed: %w", i, err) } } @@ -126,7 +133,7 @@ func (b *DBESDKBenchmark) runThroughputTest(dataSize int, iterations int) (*Benc for i := 0; i < iterations; i++ { itemId := fmt.Sprintf("%d", 1000+i) // Use numeric string, offset to avoid warmup conflicts iterationStart := time.Now() - putMs, getMs, err := b.runPutGetCycle(testData, itemId) + putMs, getMs, err := b.runBatchPutGetCycle(testData, itemId) if err != nil { return nil, fmt.Errorf("measurement iteration %d failed: %w", i, err) } @@ -244,7 +251,7 @@ func (b *DBESDKBenchmark) runMemoryTest(dataSize int) (*BenchmarkResult, error) // Run operation operationStart := time.Now() itemId := fmt.Sprintf("%d", 2000+i) // Use numeric string, offset to avoid conflicts - _, _, err := b.runPutGetCycle(data, itemId) + _, _, err := b.runBatchPutGetCycle(data, itemId) operationDuration := time.Since(operationStart) close(stopSampling) From f52afbe2e81e93a78b551a4ddf705a464116c8b0 Mon Sep 17 00:00:00 2001 From: rishav-karanjit Date: Thu, 4 Sep 2025 10:58:43 -0700 Subject: [PATCH 04/33] auto commit --- .../go/benchmark/benchmark_tests.go | 198 +++++++++--------- .../go/config/test-scenarios.yaml | 7 +- 2 files changed, 104 insertions(+), 101 deletions(-) diff --git a/db-esdk-performance-testing/go/benchmark/benchmark_tests.go b/db-esdk-performance-testing/go/benchmark/benchmark_tests.go index d8c379c2a..1562d040e 100644 --- a/db-esdk-performance-testing/go/benchmark/benchmark_tests.go +++ b/db-esdk-performance-testing/go/benchmark/benchmark_tests.go @@ -9,6 +9,7 @@ import ( "log" "runtime" "runtime/metrics" + "slices" "sort" "strconv" "sync" @@ -23,7 +24,7 @@ import ( // === Helper Functions === // runBatchPutGetCycle performs a BatchWriteItem-BatchGetItem cycle with 25 items and measures performance -func (b *DBESDKBenchmark) runBatchPutGetCycle(data []byte, baseItemId string) (float64, float64, error) { +func (b *DBESDKBenchmark) runBatchPutGetCycle(data []byte) (float64, float64, error) { ctx := context.Background() tableName := b.Config.TableName @@ -81,7 +82,7 @@ func (b *DBESDKBenchmark) runBatchPutGetCycle(data []byte, baseItemId string) (f for _, item := range items { retrievedData, ok := item["attribute1"].(*types.AttributeValueMemberB) - if !ok || len(retrievedData.Value) != len(data) { + if !ok || !slices.Equal(retrievedData.Value, data) { return 0, 0, fmt.Errorf("data verification failed") } } @@ -113,8 +114,7 @@ func (b *DBESDKBenchmark) runThroughputTest(dataSize int, iterations int) (*Benc // Warmup for i := 0; i < b.Config.Iterations.Warmup; i++ { - itemId := fmt.Sprintf("%d", i) // Use numeric string for Number attribute - if _, _, err := b.runBatchPutGetCycle(testData, itemId); err != nil { + if _, _, err := b.runBatchPutGetCycle(testData); err != nil { return nil, fmt.Errorf("warmup iteration %d failed: %w", i, err) } } @@ -131,9 +131,8 @@ func (b *DBESDKBenchmark) runThroughputTest(dataSize int, iterations int) (*Benc startTime := time.Now() for i := 0; i < iterations; i++ { - itemId := fmt.Sprintf("%d", 1000+i) // Use numeric string, offset to avoid warmup conflicts iterationStart := time.Now() - putMs, getMs, err := b.runBatchPutGetCycle(testData, itemId) + putMs, getMs, err := b.runBatchPutGetCycle(testData) if err != nil { return nil, fmt.Errorf("measurement iteration %d failed: %w", i, err) } @@ -250,8 +249,7 @@ func (b *DBESDKBenchmark) runMemoryTest(dataSize int) (*BenchmarkResult, error) // Run operation operationStart := time.Now() - itemId := fmt.Sprintf("%d", 2000+i) // Use numeric string, offset to avoid conflicts - _, _, err := b.runBatchPutGetCycle(data, itemId) + _, _, err := b.runBatchPutGetCycle(data) operationDuration := time.Since(operationStart) close(stopSampling) @@ -327,77 +325,77 @@ func (b *DBESDKBenchmark) runMemoryTest(dataSize int) (*BenchmarkResult, error) // === 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.runEncryptDecryptCycle(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 -// } +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.runBatchPutGetCycle(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 +} // === Test Orchestration === @@ -430,22 +428,22 @@ func (b *DBESDKBenchmark) runMemoryTests(dataSizes []int) { } // 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) -// } -// } -// } -// } +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 { @@ -470,11 +468,11 @@ func (b *DBESDKBenchmark) RunAllBenchmarks() error { 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)") - // } + 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 diff --git a/db-esdk-performance-testing/go/config/test-scenarios.yaml b/db-esdk-performance-testing/go/config/test-scenarios.yaml index 9464a979b..d5d57d2fa 100644 --- a/db-esdk-performance-testing/go/config/test-scenarios.yaml +++ b/db-esdk-performance-testing/go/config/test-scenarios.yaml @@ -3,8 +3,13 @@ # 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: - - 400 # 400KB + - 102400 # 100KB + - 400000 # 400KB # Quick test configuration (reduced test set for faster execution) quick_config: From bb8af55f50b61765696484b4664b08ed635693b0 Mon Sep 17 00:00:00 2001 From: rishav-karanjit Date: Thu, 4 Sep 2025 14:38:13 -0700 Subject: [PATCH 05/33] auto commit --- .../go/benchmark/config.go | 7 +++++ .../go/benchmark/dbesdk_benchmark.go | 25 ++++++++++++++++ .../go/benchmark/keyringsetup.go | 30 +++++++++++++++++++ .../go/config/test-scenarios.yaml | 2 ++ 4 files changed, 64 insertions(+) create mode 100644 db-esdk-performance-testing/go/benchmark/keyringsetup.go diff --git a/db-esdk-performance-testing/go/benchmark/config.go b/db-esdk-performance-testing/go/benchmark/config.go index 46bfb08dd..2d50b3164 100644 --- a/db-esdk-performance-testing/go/benchmark/config.go +++ b/db-esdk-performance-testing/go/benchmark/config.go @@ -10,6 +10,12 @@ import ( "gopkg.in/yaml.v3" ) +type KeyringType string + +const ( + RawAESKeying KeyringType = "raw-aes" +) + // TestConfig represents the configuration for benchmark tests type TestConfig struct { DataSizes struct { @@ -24,6 +30,7 @@ type TestConfig struct { 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 diff --git a/db-esdk-performance-testing/go/benchmark/dbesdk_benchmark.go b/db-esdk-performance-testing/go/benchmark/dbesdk_benchmark.go index 4e7dd7177..23b8bd43e 100644 --- a/db-esdk-performance-testing/go/benchmark/dbesdk_benchmark.go +++ b/db-esdk-performance-testing/go/benchmark/dbesdk_benchmark.go @@ -58,6 +58,11 @@ func New(configPath string) (*DBESDKBenchmark, error) { } 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(); err != nil { return nil, fmt.Errorf("failed to setup DB-ESDK: %w", err) @@ -69,6 +74,26 @@ func New(configPath string) (*DBESDKBenchmark, error) { 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() error { ddbTableName := b.Config.TableName diff --git a/db-esdk-performance-testing/go/benchmark/keyringsetup.go b/db-esdk-performance-testing/go/benchmark/keyringsetup.go new file mode 100644 index 000000000..da53309ee --- /dev/null +++ b/db-esdk-performance-testing/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/go/config/test-scenarios.yaml b/db-esdk-performance-testing/go/config/test-scenarios.yaml index d5d57d2fa..26a0a5c38 100644 --- a/db-esdk-performance-testing/go/config/test-scenarios.yaml +++ b/db-esdk-performance-testing/go/config/test-scenarios.yaml @@ -41,3 +41,5 @@ concurrency_levels: - 16 table_name: "dbesdk-performance-testing" # DynamoDB table name + +keyring: "raw-aes" \ No newline at end of file From effac2d96cb7a1176ff0fb7de6c67ef04345aa31 Mon Sep 17 00:00:00 2001 From: rishav-karanjit Date: Thu, 4 Sep 2025 14:40:29 -0700 Subject: [PATCH 06/33] auto commit --- db-esdk-performance-testing/{go => }/benchmark/benchmark_tests.go | 0 db-esdk-performance-testing/{go => }/benchmark/config.go | 0 .../{go => }/benchmark/dbesdk_benchmark.go | 0 db-esdk-performance-testing/{go => }/benchmark/keyringsetup.go | 0 db-esdk-performance-testing/{go => }/benchmark/results.go | 0 5 files changed, 0 insertions(+), 0 deletions(-) rename db-esdk-performance-testing/{go => }/benchmark/benchmark_tests.go (100%) rename db-esdk-performance-testing/{go => }/benchmark/config.go (100%) rename db-esdk-performance-testing/{go => }/benchmark/dbesdk_benchmark.go (100%) rename db-esdk-performance-testing/{go => }/benchmark/keyringsetup.go (100%) rename db-esdk-performance-testing/{go => }/benchmark/results.go (100%) diff --git a/db-esdk-performance-testing/go/benchmark/benchmark_tests.go b/db-esdk-performance-testing/benchmark/benchmark_tests.go similarity index 100% rename from db-esdk-performance-testing/go/benchmark/benchmark_tests.go rename to db-esdk-performance-testing/benchmark/benchmark_tests.go diff --git a/db-esdk-performance-testing/go/benchmark/config.go b/db-esdk-performance-testing/benchmark/config.go similarity index 100% rename from db-esdk-performance-testing/go/benchmark/config.go rename to db-esdk-performance-testing/benchmark/config.go diff --git a/db-esdk-performance-testing/go/benchmark/dbesdk_benchmark.go b/db-esdk-performance-testing/benchmark/dbesdk_benchmark.go similarity index 100% rename from db-esdk-performance-testing/go/benchmark/dbesdk_benchmark.go rename to db-esdk-performance-testing/benchmark/dbesdk_benchmark.go diff --git a/db-esdk-performance-testing/go/benchmark/keyringsetup.go b/db-esdk-performance-testing/benchmark/keyringsetup.go similarity index 100% rename from db-esdk-performance-testing/go/benchmark/keyringsetup.go rename to db-esdk-performance-testing/benchmark/keyringsetup.go diff --git a/db-esdk-performance-testing/go/benchmark/results.go b/db-esdk-performance-testing/benchmark/results.go similarity index 100% rename from db-esdk-performance-testing/go/benchmark/results.go rename to db-esdk-performance-testing/benchmark/results.go From 64503261014e6d640c88a63cfd0750d5cf3ba506 Mon Sep 17 00:00:00 2001 From: rishav-karanjit Date: Thu, 4 Sep 2025 14:47:59 -0700 Subject: [PATCH 07/33] auto commit --- db-esdk-performance-testing/{ => benchmark}/go/README.md | 0 db-esdk-performance-testing/benchmark/{ => go}/benchmark_tests.go | 0 db-esdk-performance-testing/benchmark/{ => go}/config.go | 0 .../{ => benchmark}/go/config/test-scenarios.yaml | 0 .../benchmark/{ => go}/dbesdk_benchmark.go | 0 db-esdk-performance-testing/{ => benchmark}/go/go.mod | 0 db-esdk-performance-testing/{ => benchmark}/go/go.sum | 0 db-esdk-performance-testing/benchmark/{ => go}/keyringsetup.go | 0 db-esdk-performance-testing/{ => benchmark}/go/main.go | 0 db-esdk-performance-testing/benchmark/{ => go}/results.go | 0 10 files changed, 0 insertions(+), 0 deletions(-) rename db-esdk-performance-testing/{ => benchmark}/go/README.md (100%) rename db-esdk-performance-testing/benchmark/{ => go}/benchmark_tests.go (100%) rename db-esdk-performance-testing/benchmark/{ => go}/config.go (100%) rename db-esdk-performance-testing/{ => benchmark}/go/config/test-scenarios.yaml (100%) rename db-esdk-performance-testing/benchmark/{ => go}/dbesdk_benchmark.go (100%) rename db-esdk-performance-testing/{ => benchmark}/go/go.mod (100%) rename db-esdk-performance-testing/{ => benchmark}/go/go.sum (100%) rename db-esdk-performance-testing/benchmark/{ => go}/keyringsetup.go (100%) rename db-esdk-performance-testing/{ => benchmark}/go/main.go (100%) rename db-esdk-performance-testing/benchmark/{ => go}/results.go (100%) diff --git a/db-esdk-performance-testing/go/README.md b/db-esdk-performance-testing/benchmark/go/README.md similarity index 100% rename from db-esdk-performance-testing/go/README.md rename to db-esdk-performance-testing/benchmark/go/README.md diff --git a/db-esdk-performance-testing/benchmark/benchmark_tests.go b/db-esdk-performance-testing/benchmark/go/benchmark_tests.go similarity index 100% rename from db-esdk-performance-testing/benchmark/benchmark_tests.go rename to db-esdk-performance-testing/benchmark/go/benchmark_tests.go diff --git a/db-esdk-performance-testing/benchmark/config.go b/db-esdk-performance-testing/benchmark/go/config.go similarity index 100% rename from db-esdk-performance-testing/benchmark/config.go rename to db-esdk-performance-testing/benchmark/go/config.go diff --git a/db-esdk-performance-testing/go/config/test-scenarios.yaml b/db-esdk-performance-testing/benchmark/go/config/test-scenarios.yaml similarity index 100% rename from db-esdk-performance-testing/go/config/test-scenarios.yaml rename to db-esdk-performance-testing/benchmark/go/config/test-scenarios.yaml diff --git a/db-esdk-performance-testing/benchmark/dbesdk_benchmark.go b/db-esdk-performance-testing/benchmark/go/dbesdk_benchmark.go similarity index 100% rename from db-esdk-performance-testing/benchmark/dbesdk_benchmark.go rename to db-esdk-performance-testing/benchmark/go/dbesdk_benchmark.go diff --git a/db-esdk-performance-testing/go/go.mod b/db-esdk-performance-testing/benchmark/go/go.mod similarity index 100% rename from db-esdk-performance-testing/go/go.mod rename to db-esdk-performance-testing/benchmark/go/go.mod diff --git a/db-esdk-performance-testing/go/go.sum b/db-esdk-performance-testing/benchmark/go/go.sum similarity index 100% rename from db-esdk-performance-testing/go/go.sum rename to db-esdk-performance-testing/benchmark/go/go.sum diff --git a/db-esdk-performance-testing/benchmark/keyringsetup.go b/db-esdk-performance-testing/benchmark/go/keyringsetup.go similarity index 100% rename from db-esdk-performance-testing/benchmark/keyringsetup.go rename to db-esdk-performance-testing/benchmark/go/keyringsetup.go diff --git a/db-esdk-performance-testing/go/main.go b/db-esdk-performance-testing/benchmark/go/main.go similarity index 100% rename from db-esdk-performance-testing/go/main.go rename to db-esdk-performance-testing/benchmark/go/main.go diff --git a/db-esdk-performance-testing/benchmark/results.go b/db-esdk-performance-testing/benchmark/go/results.go similarity index 100% rename from db-esdk-performance-testing/benchmark/results.go rename to db-esdk-performance-testing/benchmark/go/results.go From 19f4ea97b8d4bac8185f0df6afe1335782617dce Mon Sep 17 00:00:00 2001 From: rishav-karanjit Date: Thu, 4 Sep 2025 14:55:09 -0700 Subject: [PATCH 08/33] auto commit --- .../{benchmark => benchmarks}/go/README.md | 0 .../{benchmark => benchmarks}/go/benchmark_tests.go | 0 .../{benchmark => benchmarks}/go/config.go | 0 .../{benchmark => benchmarks}/go/config/test-scenarios.yaml | 0 .../{benchmark => benchmarks}/go/dbesdk_benchmark.go | 0 .../{benchmark => benchmarks}/go/go.mod | 5 ++--- .../{benchmark => benchmarks}/go/go.sum | 0 .../{benchmark => benchmarks}/go/keyringsetup.go | 0 .../{benchmark => benchmarks}/go/main.go | 0 .../{benchmark => benchmarks}/go/results.go | 0 10 files changed, 2 insertions(+), 3 deletions(-) rename db-esdk-performance-testing/{benchmark => benchmarks}/go/README.md (100%) rename db-esdk-performance-testing/{benchmark => benchmarks}/go/benchmark_tests.go (100%) rename db-esdk-performance-testing/{benchmark => benchmarks}/go/config.go (100%) rename db-esdk-performance-testing/{benchmark => benchmarks}/go/config/test-scenarios.yaml (100%) rename db-esdk-performance-testing/{benchmark => benchmarks}/go/dbesdk_benchmark.go (100%) rename db-esdk-performance-testing/{benchmark => benchmarks}/go/go.mod (91%) rename db-esdk-performance-testing/{benchmark => benchmarks}/go/go.sum (100%) rename db-esdk-performance-testing/{benchmark => benchmarks}/go/keyringsetup.go (100%) rename db-esdk-performance-testing/{benchmark => benchmarks}/go/main.go (100%) rename db-esdk-performance-testing/{benchmark => benchmarks}/go/results.go (100%) diff --git a/db-esdk-performance-testing/benchmark/go/README.md b/db-esdk-performance-testing/benchmarks/go/README.md similarity index 100% rename from db-esdk-performance-testing/benchmark/go/README.md rename to db-esdk-performance-testing/benchmarks/go/README.md diff --git a/db-esdk-performance-testing/benchmark/go/benchmark_tests.go b/db-esdk-performance-testing/benchmarks/go/benchmark_tests.go similarity index 100% rename from db-esdk-performance-testing/benchmark/go/benchmark_tests.go rename to db-esdk-performance-testing/benchmarks/go/benchmark_tests.go diff --git a/db-esdk-performance-testing/benchmark/go/config.go b/db-esdk-performance-testing/benchmarks/go/config.go similarity index 100% rename from db-esdk-performance-testing/benchmark/go/config.go rename to db-esdk-performance-testing/benchmarks/go/config.go diff --git a/db-esdk-performance-testing/benchmark/go/config/test-scenarios.yaml b/db-esdk-performance-testing/benchmarks/go/config/test-scenarios.yaml similarity index 100% rename from db-esdk-performance-testing/benchmark/go/config/test-scenarios.yaml rename to db-esdk-performance-testing/benchmarks/go/config/test-scenarios.yaml diff --git a/db-esdk-performance-testing/benchmark/go/dbesdk_benchmark.go b/db-esdk-performance-testing/benchmarks/go/dbesdk_benchmark.go similarity index 100% rename from db-esdk-performance-testing/benchmark/go/dbesdk_benchmark.go rename to db-esdk-performance-testing/benchmarks/go/dbesdk_benchmark.go diff --git a/db-esdk-performance-testing/benchmark/go/go.mod b/db-esdk-performance-testing/benchmarks/go/go.mod similarity index 91% rename from db-esdk-performance-testing/benchmark/go/go.mod rename to db-esdk-performance-testing/benchmarks/go/go.mod index 85a94a38a..efc3dd10c 100644 --- a/db-esdk-performance-testing/benchmark/go/go.mod +++ b/db-esdk-performance-testing/benchmarks/go/go.mod @@ -1,15 +1,14 @@ -module github.com/aws/aws-encryption-sdk/esdk-performance-testing/benchmarks/go +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/ +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-encryption-sdk/releases/go/encryption-sdk v0.2.0 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/schollz/progressbar/v3 v3.14.1 diff --git a/db-esdk-performance-testing/benchmark/go/go.sum b/db-esdk-performance-testing/benchmarks/go/go.sum similarity index 100% rename from db-esdk-performance-testing/benchmark/go/go.sum rename to db-esdk-performance-testing/benchmarks/go/go.sum diff --git a/db-esdk-performance-testing/benchmark/go/keyringsetup.go b/db-esdk-performance-testing/benchmarks/go/keyringsetup.go similarity index 100% rename from db-esdk-performance-testing/benchmark/go/keyringsetup.go rename to db-esdk-performance-testing/benchmarks/go/keyringsetup.go diff --git a/db-esdk-performance-testing/benchmark/go/main.go b/db-esdk-performance-testing/benchmarks/go/main.go similarity index 100% rename from db-esdk-performance-testing/benchmark/go/main.go rename to db-esdk-performance-testing/benchmarks/go/main.go diff --git a/db-esdk-performance-testing/benchmark/go/results.go b/db-esdk-performance-testing/benchmarks/go/results.go similarity index 100% rename from db-esdk-performance-testing/benchmark/go/results.go rename to db-esdk-performance-testing/benchmarks/go/results.go From f386ffc326de18df15e7bfdb0edc5e0f19615004 Mon Sep 17 00:00:00 2001 From: rishav-karanjit Date: Thu, 4 Sep 2025 14:58:09 -0700 Subject: [PATCH 09/33] benchmark --- .../benchmarks/go/{ => benchmark}/benchmark_tests.go | 0 .../benchmarks/go/{ => benchmark}/config.go | 0 .../benchmarks/go/{ => benchmark}/dbesdk_benchmark.go | 0 .../benchmarks/go/{ => benchmark}/keyringsetup.go | 0 .../benchmarks/go/{ => benchmark}/results.go | 0 5 files changed, 0 insertions(+), 0 deletions(-) rename db-esdk-performance-testing/benchmarks/go/{ => benchmark}/benchmark_tests.go (100%) rename db-esdk-performance-testing/benchmarks/go/{ => benchmark}/config.go (100%) rename db-esdk-performance-testing/benchmarks/go/{ => benchmark}/dbesdk_benchmark.go (100%) rename db-esdk-performance-testing/benchmarks/go/{ => benchmark}/keyringsetup.go (100%) rename db-esdk-performance-testing/benchmarks/go/{ => benchmark}/results.go (100%) diff --git a/db-esdk-performance-testing/benchmarks/go/benchmark_tests.go b/db-esdk-performance-testing/benchmarks/go/benchmark/benchmark_tests.go similarity index 100% rename from db-esdk-performance-testing/benchmarks/go/benchmark_tests.go rename to db-esdk-performance-testing/benchmarks/go/benchmark/benchmark_tests.go diff --git a/db-esdk-performance-testing/benchmarks/go/config.go b/db-esdk-performance-testing/benchmarks/go/benchmark/config.go similarity index 100% rename from db-esdk-performance-testing/benchmarks/go/config.go rename to db-esdk-performance-testing/benchmarks/go/benchmark/config.go diff --git a/db-esdk-performance-testing/benchmarks/go/dbesdk_benchmark.go b/db-esdk-performance-testing/benchmarks/go/benchmark/dbesdk_benchmark.go similarity index 100% rename from db-esdk-performance-testing/benchmarks/go/dbesdk_benchmark.go rename to db-esdk-performance-testing/benchmarks/go/benchmark/dbesdk_benchmark.go diff --git a/db-esdk-performance-testing/benchmarks/go/keyringsetup.go b/db-esdk-performance-testing/benchmarks/go/benchmark/keyringsetup.go similarity index 100% rename from db-esdk-performance-testing/benchmarks/go/keyringsetup.go rename to db-esdk-performance-testing/benchmarks/go/benchmark/keyringsetup.go diff --git a/db-esdk-performance-testing/benchmarks/go/results.go b/db-esdk-performance-testing/benchmarks/go/benchmark/results.go similarity index 100% rename from db-esdk-performance-testing/benchmarks/go/results.go rename to db-esdk-performance-testing/benchmarks/go/benchmark/results.go From 7d125d4e84736f0a64bbdd863c3c07d3f9a6fbcb Mon Sep 17 00:00:00 2001 From: rishav-karanjit Date: Thu, 4 Sep 2025 15:00:12 -0700 Subject: [PATCH 10/33] auto commit --- .../benchmarks/{go => }/config/test-scenarios.yaml | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename db-esdk-performance-testing/benchmarks/{go => }/config/test-scenarios.yaml (100%) diff --git a/db-esdk-performance-testing/benchmarks/go/config/test-scenarios.yaml b/db-esdk-performance-testing/benchmarks/config/test-scenarios.yaml similarity index 100% rename from db-esdk-performance-testing/benchmarks/go/config/test-scenarios.yaml rename to db-esdk-performance-testing/benchmarks/config/test-scenarios.yaml From cfaa5622b8273ed61efe816369e9efb00e0c6b16 Mon Sep 17 00:00:00 2001 From: rishav-karanjit Date: Thu, 4 Sep 2025 15:03:10 -0700 Subject: [PATCH 11/33] auto commit --- .../benchmarks/config/test-scenarios.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/db-esdk-performance-testing/benchmarks/config/test-scenarios.yaml b/db-esdk-performance-testing/benchmarks/config/test-scenarios.yaml index 26a0a5c38..cb0ca4fca 100644 --- a/db-esdk-performance-testing/benchmarks/config/test-scenarios.yaml +++ b/db-esdk-performance-testing/benchmarks/config/test-scenarios.yaml @@ -1,4 +1,4 @@ -# ESDK Performance Test Scenarios Configuration +# DB-ESDK Performance Test Scenarios Configuration # Data sizes to test (in bytes) # Categories are for organization only - code processes all sizes regardless of category From fb190f577e318fd857f495350e90973ffb3fd951 Mon Sep 17 00:00:00 2001 From: rishav-karanjit Date: Thu, 4 Sep 2025 15:05:57 -0700 Subject: [PATCH 12/33] auto commit --- .../benchmarks/config/test-scenarios.yaml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/db-esdk-performance-testing/benchmarks/config/test-scenarios.yaml b/db-esdk-performance-testing/benchmarks/config/test-scenarios.yaml index cb0ca4fca..394dfb3eb 100644 --- a/db-esdk-performance-testing/benchmarks/config/test-scenarios.yaml +++ b/db-esdk-performance-testing/benchmarks/config/test-scenarios.yaml @@ -40,6 +40,8 @@ concurrency_levels: - 8 - 16 -table_name: "dbesdk-performance-testing" # DynamoDB table name +# DynamoDB table name +table_name: "dbesdk-performance-testing" +# Keyring keyring: "raw-aes" \ No newline at end of file From 818dfd2fe599ead43795709b20841e92761271d6 Mon Sep 17 00:00:00 2001 From: rishav-karanjit Date: Thu, 4 Sep 2025 15:19:45 -0700 Subject: [PATCH 13/33] auto commit --- db-esdk-performance-testing/benchmarks/go/go.sum | 2 -- db-esdk-performance-testing/benchmarks/go/main.go | 2 +- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/db-esdk-performance-testing/benchmarks/go/go.sum b/db-esdk-performance-testing/benchmarks/go/go.sum index 3b287bdb0..5c23c6894 100644 --- a/db-esdk-performance-testing/benchmarks/go/go.sum +++ b/db-esdk-performance-testing/benchmarks/go/go.sum @@ -8,8 +8,6 @@ github.com/aws/aws-cryptographic-material-providers-library/releases/go/primitiv 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-encryption-sdk/releases/go/encryption-sdk v0.2.0 h1:WD+Zmu/WR3rW8u1qfuKH1T10SXQPAb/Dtv+lRceAqzQ= -github.com/aws/aws-encryption-sdk/releases/go/encryption-sdk v0.2.0/go.mod h1:dZucPyqttfAV6EEYohPSB8ZkF8yBqCiSltsK1Joa/Sg= 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= diff --git a/db-esdk-performance-testing/benchmarks/go/main.go b/db-esdk-performance-testing/benchmarks/go/main.go index ffd21f99a..74985ea9f 100644 --- a/db-esdk-performance-testing/benchmarks/go/main.go +++ b/db-esdk-performance-testing/benchmarks/go/main.go @@ -9,7 +9,7 @@ import ( "fmt" "log" - "github.com/aws/aws-encryption-sdk/esdk-performance-testing/benchmarks/go/benchmark" + "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" From 238c7b13116fd600aade3114f30f958c74081934 Mon Sep 17 00:00:00 2001 From: rishav-karanjit Date: Thu, 4 Sep 2025 15:20:26 -0700 Subject: [PATCH 14/33] auto commit --- db-esdk-performance-testing/benchmarks/go/go.mod | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/db-esdk-performance-testing/benchmarks/go/go.mod b/db-esdk-performance-testing/benchmarks/go/go.mod index efc3dd10c..e521a2d68 100644 --- a/db-esdk-performance-testing/benchmarks/go/go.mod +++ b/db-esdk-performance-testing/benchmarks/go/go.mod @@ -9,8 +9,10 @@ replace github.com/aws/aws-database-encryption-sdk-dynamodb/releases/go/dynamodb 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 @@ -21,7 +23,6 @@ require ( 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 v1.38.1 // 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 @@ -34,7 +35,6 @@ require ( 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/aws/smithy-go v1.22.5 // 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 From cb738d796df672c7c65e0bf5c01796ee8dbf679c Mon Sep 17 00:00:00 2001 From: rishav-karanjit Date: Thu, 4 Sep 2025 15:27:32 -0700 Subject: [PATCH 15/33] auto commit --- .../config/test-scenarios.yaml | 47 +++++++++++++++++++ 1 file changed, 47 insertions(+) create mode 100644 db-esdk-performance-testing/config/test-scenarios.yaml diff --git a/db-esdk-performance-testing/config/test-scenarios.yaml b/db-esdk-performance-testing/config/test-scenarios.yaml new file mode 100644 index 000000000..10668077c --- /dev/null +++ b/db-esdk-performance-testing/config/test-scenarios.yaml @@ -0,0 +1,47 @@ +# 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 + - 400000 # 400KB + +# 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" From 9b4c97a7880ecfe2c9a2ac58b1db0e9402a030c9 Mon Sep 17 00:00:00 2001 From: rishav-karanjit Date: Fri, 5 Sep 2025 11:36:30 -0700 Subject: [PATCH 16/33] auto commit --- .../go/benchmark/benchmark_tests.go | 59 +++++++++++++++---- 1 file changed, 47 insertions(+), 12 deletions(-) diff --git a/db-esdk-performance-testing/benchmarks/go/benchmark/benchmark_tests.go b/db-esdk-performance-testing/benchmarks/go/benchmark/benchmark_tests.go index 1562d040e..de83cfca1 100644 --- a/db-esdk-performance-testing/benchmarks/go/benchmark/benchmark_tests.go +++ b/db-esdk-performance-testing/benchmarks/go/benchmark/benchmark_tests.go @@ -4,12 +4,12 @@ package benchmark import ( + "bytes" "context" "fmt" "log" "runtime" "runtime/metrics" - "slices" "sort" "strconv" "sync" @@ -29,15 +29,23 @@ func (b *DBESDKBenchmark) runBatchPutGetCycle(data []byte) (float64, float64, er tableName := b.Config.TableName // Create 25 write requests with same data, different sort_key - var writeRequests []types.WriteRequest + var items []map[string]types.AttributeValue + for i := 0; i < 25; i++ { item := map[string]types.AttributeValue{ "partition_key": &types.AttributeValueMemberS{Value: "benchmark-test"}, "sort_key": &types.AttributeValueMemberN{Value: strconv.Itoa(i)}, - "attribute1": &types.AttributeValueMemberB{Value: data}, - "attribute2": &types.AttributeValueMemberS{Value: "sign me!"}, - ":attribute3": &types.AttributeValueMemberS{Value: "ignore me!"}, + "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!"}, } + items = append(items, item) + } + + var writeRequests []types.WriteRequest + for _, item := range items { writeRequests = append(writeRequests, types.WriteRequest{ PutRequest: &types.PutRequest{Item: item}, }) @@ -75,15 +83,42 @@ func (b *DBESDKBenchmark) runBatchPutGetCycle(data []byte) (float64, float64, er batchGetDuration := time.Since(batchGetStart).Seconds() * 1000 // Verify 25 items retrieved with correct data size - items := result.Responses[tableName] - if len(items) != 25 { - return 0, 0, fmt.Errorf("expected 25 items, got %d", len(items)) + returnedItems := result.Responses[tableName] + if len(returnedItems) != 25 { + return 0, 0, fmt.Errorf("expected 25 items, got %d", len(returnedItems)) } - for _, item := range items { - retrievedData, ok := item["attribute1"].(*types.AttributeValueMemberB) - if !ok || !slices.Equal(retrievedData.Value, data) { - return 0, 0, fmt.Errorf("data verification failed") + // Verify each returned item + for i, item := range returnedItems { + if _, ok := item["attribute1"]; !ok { + return 0, 0, fmt.Errorf("item %d missing attribute1", i) + } + + // Verify attribute1 + if attr1, ok := item["attribute1"].(*types.AttributeValueMemberM); ok { + if dataAttr, ok := attr1.Value["data"].(*types.AttributeValueMemberB); ok { + if !bytes.Equal(dataAttr.Value, data) { + return 0, 0, fmt.Errorf("item %d data mismatch", i) + } + } + } + + // Verify attribute2 value + if attr2, ok := item["attribute2"].(*types.AttributeValueMemberS); ok { + if attr2.Value != "sign me!" { + return 0, 0, fmt.Errorf("item %d attribute2 mismatch: got %s", i, attr2.Value) + } + } else { + return 0, 0, fmt.Errorf("item %d attribute2 wrong type", i) + } + + // Verify :attribute3 value + if attr3, ok := item[":attribute3"].(*types.AttributeValueMemberS); ok { + if attr3.Value != "ignore me!" { + return 0, 0, fmt.Errorf("item %d :attribute3 mismatch: got %s", i, attr3.Value) + } + } else { + return 0, 0, fmt.Errorf("item %d :attribute3 wrong type", i) } } From 13e48e64294c26e0204641f7c5eaebe7dae90769 Mon Sep 17 00:00:00 2001 From: rishav-karanjit Date: Fri, 5 Sep 2025 11:37:29 -0700 Subject: [PATCH 17/33] Calculate Item Size --- .../go/benchmark/benchmark_tests.go | 62 +++++++++++++++++++ 1 file changed, 62 insertions(+) diff --git a/db-esdk-performance-testing/benchmarks/go/benchmark/benchmark_tests.go b/db-esdk-performance-testing/benchmarks/go/benchmark/benchmark_tests.go index de83cfca1..51bab75ff 100644 --- a/db-esdk-performance-testing/benchmarks/go/benchmark/benchmark_tests.go +++ b/db-esdk-performance-testing/benchmarks/go/benchmark/benchmark_tests.go @@ -23,6 +23,68 @@ import ( // === Helper Functions === +func CalculateItemSize(item map[string]types.AttributeValue) int { + totalSize := 0 + + for attributeName, attributeValue := range item { + // Add attribute name size + totalSize += len(attributeName) + + // Add attribute value size + totalSize += calculateAttributeValueSize(attributeValue) + } + + return totalSize +} + +func calculateAttributeValueSize(av types.AttributeValue) int { + switch v := av.(type) { + case *types.AttributeValueMemberS: + return len(v.Value) + case *types.AttributeValueMemberN: + return len(v.Value) + case *types.AttributeValueMemberB: + return len(v.Value) + case *types.AttributeValueMemberBOOL: + return 1 + case *types.AttributeValueMemberNULL: + return 1 + case *types.AttributeValueMemberSS: + size := 0 + for _, s := range v.Value { + size += len(s) + } + return size + case *types.AttributeValueMemberNS: + size := 0 + for _, n := range v.Value { + size += len(n) + } + return size + case *types.AttributeValueMemberBS: + size := 0 + for _, b := range v.Value { + size += len(b) + } + return size + case *types.AttributeValueMemberL: + size := 0 + for _, item := range v.Value { + size += calculateAttributeValueSize(item) + } + return size + case *types.AttributeValueMemberM: + size := 0 + for key, value := range v.Value { + size += len(key) // Nested attribute name + size += calculateAttributeValueSize(value) + } + return size + default: + return 0 + } +} + // runBatchPutGetCycle performs a BatchWriteItem-BatchGetItem cycle with 25 items and measures performance func (b *DBESDKBenchmark) runBatchPutGetCycle(data []byte) (float64, float64, error) { ctx := context.Background() From 98959a856f0d189c980928673a2227224f6a0bf0 Mon Sep 17 00:00:00 2001 From: rishav-karanjit Date: Fri, 5 Sep 2025 11:39:05 -0700 Subject: [PATCH 18/33] Revert "Calculate Item Size" This reverts commit 13e48e64294c26e0204641f7c5eaebe7dae90769. --- .../go/benchmark/benchmark_tests.go | 62 ------------------- 1 file changed, 62 deletions(-) diff --git a/db-esdk-performance-testing/benchmarks/go/benchmark/benchmark_tests.go b/db-esdk-performance-testing/benchmarks/go/benchmark/benchmark_tests.go index 51bab75ff..de83cfca1 100644 --- a/db-esdk-performance-testing/benchmarks/go/benchmark/benchmark_tests.go +++ b/db-esdk-performance-testing/benchmarks/go/benchmark/benchmark_tests.go @@ -23,68 +23,6 @@ import ( // === Helper Functions === -func CalculateItemSize(item map[string]types.AttributeValue) int { - totalSize := 0 - - for attributeName, attributeValue := range item { - // Add attribute name size - totalSize += len(attributeName) - - // Add attribute value size - totalSize += calculateAttributeValueSize(attributeValue) - } - - return totalSize -} - -func calculateAttributeValueSize(av types.AttributeValue) int { - switch v := av.(type) { - case *types.AttributeValueMemberS: - return len(v.Value) - case *types.AttributeValueMemberN: - return len(v.Value) - case *types.AttributeValueMemberB: - return len(v.Value) - case *types.AttributeValueMemberBOOL: - return 1 - case *types.AttributeValueMemberNULL: - return 1 - case *types.AttributeValueMemberSS: - size := 0 - for _, s := range v.Value { - size += len(s) - } - return size - case *types.AttributeValueMemberNS: - size := 0 - for _, n := range v.Value { - size += len(n) - } - return size - case *types.AttributeValueMemberBS: - size := 0 - for _, b := range v.Value { - size += len(b) - } - return size - case *types.AttributeValueMemberL: - size := 0 - for _, item := range v.Value { - size += calculateAttributeValueSize(item) - } - return size - case *types.AttributeValueMemberM: - size := 0 - for key, value := range v.Value { - size += len(key) // Nested attribute name - size += calculateAttributeValueSize(value) - } - return size - default: - return 0 - } -} - // runBatchPutGetCycle performs a BatchWriteItem-BatchGetItem cycle with 25 items and measures performance func (b *DBESDKBenchmark) runBatchPutGetCycle(data []byte) (float64, float64, error) { ctx := context.Background() From 99ff591a2c9c01abf6b3d65494ba0e3b2b502ae7 Mon Sep 17 00:00:00 2001 From: rishav-karanjit Date: Fri, 5 Sep 2025 13:53:34 -0700 Subject: [PATCH 19/33] benchmark --- .../benchmarks/go/benchmark/testRunners.go | 352 ++++++++++++++++++ 1 file changed, 352 insertions(+) create mode 100644 db-esdk-performance-testing/benchmarks/go/benchmark/testRunners.go 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..ea1dfd06d --- /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) + + // Get baseline + metrics.Read(samples) + beforeHeap := samples[0].Value.Uint64() + beforeAllocs := samples[1].Value.Uint64() + + // Start continuous sampling + stopSampling := make(chan bool) + var continuousSamples []MemorySample + var samplingMutex sync.Mutex + + go func() { + sampledData := b.sampleMemoryContinuously(beforeHeap, beforeAllocs, stopSampling) + samplingMutex.Lock() + continuousSamples = sampledData + samplingMutex.Unlock() + }() + + // Run operation + operationStart := time.Now() + _, _, err := b.runBatchPutGetCycle(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.runBatchPutGetCycle(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.runBatchPutGetCycle(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.runBatchPutGetCycle(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 +} From d57edd4c1841c2f65b8aebf324b642521b378807 Mon Sep 17 00:00:00 2001 From: rishav-karanjit Date: Fri, 5 Sep 2025 13:54:14 -0700 Subject: [PATCH 20/33] auto commit --- .../go/benchmark/benchmark_tests.go | 342 ------------------ 1 file changed, 342 deletions(-) diff --git a/db-esdk-performance-testing/benchmarks/go/benchmark/benchmark_tests.go b/db-esdk-performance-testing/benchmarks/go/benchmark/benchmark_tests.go index de83cfca1..f15485993 100644 --- a/db-esdk-performance-testing/benchmarks/go/benchmark/benchmark_tests.go +++ b/db-esdk-performance-testing/benchmarks/go/benchmark/benchmark_tests.go @@ -7,18 +7,13 @@ import ( "bytes" "context" "fmt" - "log" - "runtime" "runtime/metrics" - "sort" "strconv" - "sync" "time" "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" - "github.com/schollz/progressbar/v3" ) // === Helper Functions === @@ -139,76 +134,6 @@ func (b *DBESDKBenchmark) shouldRunTestType(testType string) bool { return false } -// === 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.runBatchPutGetCycle(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.runBatchPutGetCycle(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 -} - // === Memory Test Implementation === // sampleMemoryContinuously runs continuous memory sampling during operation @@ -245,270 +170,3 @@ func (b *DBESDKBenchmark) sampleMemoryContinuously(beforeHeap, beforeAllocs uint } } } - -// 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) - - // Get baseline - metrics.Read(samples) - beforeHeap := samples[0].Value.Uint64() - beforeAllocs := samples[1].Value.Uint64() - - // Start continuous sampling - stopSampling := make(chan bool) - var continuousSamples []MemorySample - var samplingMutex sync.Mutex - - go func() { - sampledData := b.sampleMemoryContinuously(beforeHeap, beforeAllocs, stopSampling) - samplingMutex.Lock() - continuousSamples = sampledData - samplingMutex.Unlock() - }() - - // Run operation - operationStart := time.Now() - _, _, err := b.runBatchPutGetCycle(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.runBatchPutGetCycle(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 -} - -// === 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 -} From 52ae369a80553933f4049b3ff0f846fa6f909fac Mon Sep 17 00:00:00 2001 From: rishav-karanjit Date: Sat, 6 Sep 2025 13:47:00 -0700 Subject: [PATCH 21/33] Item encryptor --- .../benchmarks/config/test-scenarios.yaml | 2 +- .../go/benchmark/benchmark_tests.go | 44 +++++++++ .../go/benchmark/dbesdk_benchmark.go | 91 +++++++++++-------- .../benchmarks/go/benchmark/testRunners.go | 8 +- .../config/test-scenarios.yaml | 2 +- 5 files changed, 101 insertions(+), 46 deletions(-) diff --git a/db-esdk-performance-testing/benchmarks/config/test-scenarios.yaml b/db-esdk-performance-testing/benchmarks/config/test-scenarios.yaml index 394dfb3eb..ca0fc14aa 100644 --- a/db-esdk-performance-testing/benchmarks/config/test-scenarios.yaml +++ b/db-esdk-performance-testing/benchmarks/config/test-scenarios.yaml @@ -9,7 +9,7 @@ data_sizes: - 10240 # 10KB medium: - 102400 # 100KB - - 400000 # 400KB + - 50000000 # 50MB # Quick test configuration (reduced test set for faster execution) quick_config: diff --git a/db-esdk-performance-testing/benchmarks/go/benchmark/benchmark_tests.go b/db-esdk-performance-testing/benchmarks/go/benchmark/benchmark_tests.go index f15485993..5fe1ddf5c 100644 --- a/db-esdk-performance-testing/benchmarks/go/benchmark/benchmark_tests.go +++ b/db-esdk-performance-testing/benchmarks/go/benchmark/benchmark_tests.go @@ -7,10 +7,12 @@ import ( "bytes" "context" "fmt" + "reflect" "runtime/metrics" "strconv" "time" + dbesdkitemencryptortypes "github.com/aws/aws-database-encryption-sdk-dynamodb/releases/go/dynamodb-esdk/awscryptographydbencryptionsdkdynamodbitemencryptorsmithygeneratedtypes" "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" @@ -120,6 +122,48 @@ func (b *DBESDKBenchmark) runBatchPutGetCycle(data []byte) (float64, float64, er return batchWriteDuration, batchGetDuration, nil } +// runBatchPutGetCycle performs a BatchWriteItem-BatchGetItem 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 { diff --git a/db-esdk-performance-testing/benchmarks/go/benchmark/dbesdk_benchmark.go b/db-esdk-performance-testing/benchmarks/go/benchmark/dbesdk_benchmark.go index 23b8bd43e..84ce82d1d 100644 --- a/db-esdk-performance-testing/benchmarks/go/benchmark/dbesdk_benchmark.go +++ b/db-esdk-performance-testing/benchmarks/go/benchmark/dbesdk_benchmark.go @@ -13,6 +13,8 @@ import ( 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" @@ -32,12 +34,13 @@ const ( // DBESDKBenchmark is the main benchmark struct type DBESDKBenchmark struct { - Config TestConfig - DbesdkClient *dynamodb.Client - Keyring mpltypes.IKeyring - Results []BenchmarkResult - CPUCount int - TotalMemoryGB float64 + Config TestConfig + DbesdkClient *dynamodb.Client + ItemEncryptorClient *itemencryptor.Client + Keyring mpltypes.IKeyring + Results []BenchmarkResult + CPUCount int + TotalMemoryGB float64 } // New creates a new benchmark instance @@ -64,7 +67,7 @@ func New(configPath string) (*DBESDKBenchmark, error) { } // Setup DB-ESDK - if err := benchmark.setupDBESDK(); err != nil { + if err := benchmark.setupDBESDK(false); err != nil { return nil, fmt.Errorf("failed to setup DB-ESDK: %w", err) } @@ -95,35 +98,7 @@ func (b *DBESDKBenchmark) setupMPL() error { } // setupDBESDK initializes the DynamoDB client with DB-ESDK middleware and creates a default keyring which is AES keyring -func (b *DBESDKBenchmark) setupDBESDK() error { - ddbTableName := b.Config.TableName - - // 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) - } - - // Create default AES-256 keyring - key := make([]byte, 32) // 256-bit key - if _, err := rand.Read(key); err != nil { - return 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 fmt.Errorf("failed to create keyring: %w", err) - } - b.Keyring = keyring - +func (b *DBESDKBenchmark) setupDBESDK(useItemEncryptor bool) error { attributeActions := map[string]dbesdkstructuredencryptiontypes.CryptoAction{ "partition_key": dbesdkstructuredencryptiontypes.CryptoActionSignOnly, "sort_key": dbesdkstructuredencryptiontypes.CryptoActionSignOnly, @@ -137,22 +112,41 @@ func (b *DBESDKBenchmark) setupDBESDK() error { 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: ddbTableName, + LogicalTableName: b.Config.TableName, PartitionKeyName: partitionKey, SortKeyName: &sortKeyName, AttributeActionsOnEncrypt: attributeActions, - Keyring: keyring, + Keyring: b.Keyring, AllowedUnsignedAttributePrefix: &allowedUnsignedAttributePrefix, AlgorithmSuiteId: &algorithmSuiteID, } tableConfigsMap := make(map[string]dbesdkdynamodbencryptiontypes.DynamoDbTableEncryptionConfig) - tableConfigsMap[ddbTableName] = tableConfig + 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) { @@ -161,7 +155,24 @@ func (b *DBESDKBenchmark) setupDBESDK() error { b.DbesdkClient = ddb - log.Println("ESDK client initialized successfully") + 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 } diff --git a/db-esdk-performance-testing/benchmarks/go/benchmark/testRunners.go b/db-esdk-performance-testing/benchmarks/go/benchmark/testRunners.go index ea1dfd06d..53bb3ff9b 100644 --- a/db-esdk-performance-testing/benchmarks/go/benchmark/testRunners.go +++ b/db-esdk-performance-testing/benchmarks/go/benchmark/testRunners.go @@ -133,7 +133,7 @@ func (b *DBESDKBenchmark) runMemoryTest(dataSize int) (*BenchmarkResult, error) // Run operation operationStart := time.Now() - _, _, err := b.runBatchPutGetCycle(data) + _, _, err := b.runItemEncryptorCycle(data) operationDuration := time.Since(operationStart) close(stopSampling) @@ -229,7 +229,7 @@ func (b *DBESDKBenchmark) runConcurrentTest(dataSize int, concurrency int, itera var workerTimes []float64 for j := 0; j < iterationsPerWorker; j++ { iterStart := time.Now() - _, _, err := b.runBatchPutGetCycle(data) + _, _, err := b.runItemEncryptorCycle(data) if err != nil { errorChan <- fmt.Errorf("worker %d iteration %d failed: %w", workerID, j, err) return @@ -291,7 +291,7 @@ func (b *DBESDKBenchmark) runThroughputTest(dataSize int, iterations int) (*Benc // Warmup for i := 0; i < b.Config.Iterations.Warmup; i++ { - if _, _, err := b.runBatchPutGetCycle(testData); err != nil { + if _, _, err := b.runItemEncryptorCycle(testData); err != nil { return nil, fmt.Errorf("warmup iteration %d failed: %w", i, err) } } @@ -309,7 +309,7 @@ func (b *DBESDKBenchmark) runThroughputTest(dataSize int, iterations int) (*Benc startTime := time.Now() for i := 0; i < iterations; i++ { iterationStart := time.Now() - putMs, getMs, err := b.runBatchPutGetCycle(testData) + putMs, getMs, err := b.runItemEncryptorCycle(testData) if err != nil { return nil, fmt.Errorf("measurement iteration %d failed: %w", i, err) } diff --git a/db-esdk-performance-testing/config/test-scenarios.yaml b/db-esdk-performance-testing/config/test-scenarios.yaml index 10668077c..0338f2b0c 100644 --- a/db-esdk-performance-testing/config/test-scenarios.yaml +++ b/db-esdk-performance-testing/config/test-scenarios.yaml @@ -9,7 +9,7 @@ data_sizes: - 10240 # 10KB medium: - 102400 # 100KB - - 400000 # 400KB + - 40000000 # 40MB # Quick test configuration (reduced test set for faster execution) quick_config: From c49ffe284a85462ff1b1d165dc293847d57e2b35 Mon Sep 17 00:00:00 2001 From: rishav-karanjit Date: Sat, 6 Sep 2025 14:31:35 -0700 Subject: [PATCH 22/33] auto commit --- .../benchmarks/config/test-scenarios.yaml | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/db-esdk-performance-testing/benchmarks/config/test-scenarios.yaml b/db-esdk-performance-testing/benchmarks/config/test-scenarios.yaml index ca0fc14aa..1fe002ba2 100644 --- a/db-esdk-performance-testing/benchmarks/config/test-scenarios.yaml +++ b/db-esdk-performance-testing/benchmarks/config/test-scenarios.yaml @@ -9,7 +9,12 @@ data_sizes: - 10240 # 10KB medium: - 102400 # 100KB - - 50000000 # 50MB + - 512000 # 500KB + - 1048576 # 1MB + large: + - 10485760 # 10MB + - 52428800 # 50MB + - 104857600 # 100MB # Quick test configuration (reduced test set for faster execution) quick_config: From f4aaf5e9096f7111b646ec9f5290477576093c58 Mon Sep 17 00:00:00 2001 From: rishav-karanjit Date: Sat, 6 Sep 2025 15:04:34 -0700 Subject: [PATCH 23/33] auto commit --- .../benchmarks/go/main.go | 4 +- .../results/raw-data/go_results_released.json | 372 ++++++++++++++++++ 2 files changed, 374 insertions(+), 2 deletions(-) create mode 100644 db-esdk-performance-testing/benchmarks/results/raw-data/go_results_released.json diff --git a/db-esdk-performance-testing/benchmarks/go/main.go b/db-esdk-performance-testing/benchmarks/go/main.go index 74985ea9f..d31e8de8d 100644 --- a/db-esdk-performance-testing/benchmarks/go/main.go +++ b/db-esdk-performance-testing/benchmarks/go/main.go @@ -17,8 +17,8 @@ import ( 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") + 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() 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 + } + ] +} From 8f802c239023ba405e9681b4e3c359c2a306ffa2 Mon Sep 17 00:00:00 2001 From: rishav-karanjit Date: Sat, 6 Sep 2025 15:07:58 -0700 Subject: [PATCH 24/33] auto commit --- .../results/raw-data/go_results_robinPR.json | 372 ++++++++++++++++++ 1 file changed, 372 insertions(+) create mode 100644 db-esdk-performance-testing/benchmarks/results/raw-data/go_results_robinPR.json 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 + } + ] +} From aee7ec1589c16335dd80b993c9b3c53fe93876e7 Mon Sep 17 00:00:00 2001 From: rishav-karanjit Date: Mon, 8 Sep 2025 09:02:40 -0700 Subject: [PATCH 25/33] auto commit --- .../go/benchmark/benchmark_tests.go | 208 +++++++++--------- 1 file changed, 102 insertions(+), 106 deletions(-) diff --git a/db-esdk-performance-testing/benchmarks/go/benchmark/benchmark_tests.go b/db-esdk-performance-testing/benchmarks/go/benchmark/benchmark_tests.go index 5fe1ddf5c..db7ff0bd9 100644 --- a/db-esdk-performance-testing/benchmarks/go/benchmark/benchmark_tests.go +++ b/db-esdk-performance-testing/benchmarks/go/benchmark/benchmark_tests.go @@ -4,125 +4,121 @@ package benchmark import ( - "bytes" "context" "fmt" "reflect" "runtime/metrics" - "strconv" "time" dbesdkitemencryptortypes "github.com/aws/aws-database-encryption-sdk-dynamodb/releases/go/dynamodb-esdk/awscryptographydbencryptionsdkdynamodbitemencryptorsmithygeneratedtypes" - "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" ) // === Helper Functions === // runBatchPutGetCycle performs a BatchWriteItem-BatchGetItem cycle with 25 items and measures performance -func (b *DBESDKBenchmark) runBatchPutGetCycle(data []byte) (float64, float64, error) { - ctx := context.Background() - tableName := b.Config.TableName - - // Create 25 write requests with same data, different sort_key - var items []map[string]types.AttributeValue - - for i := 0; i < 25; i++ { - item := map[string]types.AttributeValue{ - "partition_key": &types.AttributeValueMemberS{Value: "benchmark-test"}, - "sort_key": &types.AttributeValueMemberN{Value: strconv.Itoa(i)}, - "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!"}, - } - items = append(items, item) - } - - var writeRequests []types.WriteRequest - for _, item := range items { - writeRequests = append(writeRequests, types.WriteRequest{ - PutRequest: &types.PutRequest{Item: item}, - }) - } - - // BatchWriteItem - batchWriteStart := time.Now() - _, err := b.DbesdkClient.BatchWriteItem(ctx, &dynamodb.BatchWriteItemInput{ - RequestItems: map[string][]types.WriteRequest{tableName: writeRequests}, - }) - if err != nil { - return 0, 0, fmt.Errorf("BatchWriteItem failed: %w", err) - } - batchWriteDuration := time.Since(batchWriteStart).Seconds() * 1000 - - // Create 25 keys for BatchGetItem - var keys []map[string]types.AttributeValue - for i := 0; i < 25; i++ { - keys = append(keys, map[string]types.AttributeValue{ - "partition_key": &types.AttributeValueMemberS{Value: "benchmark-test"}, - "sort_key": &types.AttributeValueMemberN{Value: strconv.Itoa(i)}, - }) - } - - // BatchGetItem - batchGetStart := time.Now() - result, err := b.DbesdkClient.BatchGetItem(ctx, &dynamodb.BatchGetItemInput{ - RequestItems: map[string]types.KeysAndAttributes{ - tableName: {Keys: keys, ConsistentRead: aws.Bool(true)}, - }, - }) - if err != nil { - return 0, 0, fmt.Errorf("BatchGetItem failed: %w", err) - } - batchGetDuration := time.Since(batchGetStart).Seconds() * 1000 - - // Verify 25 items retrieved with correct data size - returnedItems := result.Responses[tableName] - if len(returnedItems) != 25 { - return 0, 0, fmt.Errorf("expected 25 items, got %d", len(returnedItems)) - } - - // Verify each returned item - for i, item := range returnedItems { - if _, ok := item["attribute1"]; !ok { - return 0, 0, fmt.Errorf("item %d missing attribute1", i) - } - - // Verify attribute1 - if attr1, ok := item["attribute1"].(*types.AttributeValueMemberM); ok { - if dataAttr, ok := attr1.Value["data"].(*types.AttributeValueMemberB); ok { - if !bytes.Equal(dataAttr.Value, data) { - return 0, 0, fmt.Errorf("item %d data mismatch", i) - } - } - } - - // Verify attribute2 value - if attr2, ok := item["attribute2"].(*types.AttributeValueMemberS); ok { - if attr2.Value != "sign me!" { - return 0, 0, fmt.Errorf("item %d attribute2 mismatch: got %s", i, attr2.Value) - } - } else { - return 0, 0, fmt.Errorf("item %d attribute2 wrong type", i) - } - - // Verify :attribute3 value - if attr3, ok := item[":attribute3"].(*types.AttributeValueMemberS); ok { - if attr3.Value != "ignore me!" { - return 0, 0, fmt.Errorf("item %d :attribute3 mismatch: got %s", i, attr3.Value) - } - } else { - return 0, 0, fmt.Errorf("item %d :attribute3 wrong type", i) - } - } - - return batchWriteDuration, batchGetDuration, nil -} - -// runBatchPutGetCycle performs a BatchWriteItem-BatchGetItem cycle with 25 items and measures performance +// func (b *DBESDKBenchmark) runBatchPutGetCycle(data []byte) (float64, float64, error) { +// ctx := context.Background() +// tableName := b.Config.TableName + +// // Create 25 write requests with same data, different sort_key +// var items []map[string]types.AttributeValue + +// for i := 0; i < 25; i++ { +// item := map[string]types.AttributeValue{ +// "partition_key": &types.AttributeValueMemberS{Value: "benchmark-test"}, +// "sort_key": &types.AttributeValueMemberN{Value: strconv.Itoa(i)}, +// "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!"}, +// } +// items = append(items, item) +// } + +// var writeRequests []types.WriteRequest +// for _, item := range items { +// writeRequests = append(writeRequests, types.WriteRequest{ +// PutRequest: &types.PutRequest{Item: item}, +// }) +// } + +// // BatchWriteItem +// batchWriteStart := time.Now() +// _, err := b.DbesdkClient.BatchWriteItem(ctx, &dynamodb.BatchWriteItemInput{ +// RequestItems: map[string][]types.WriteRequest{tableName: writeRequests}, +// }) +// if err != nil { +// return 0, 0, fmt.Errorf("BatchWriteItem failed: %w", err) +// } +// batchWriteDuration := time.Since(batchWriteStart).Seconds() * 1000 + +// // Create 25 keys for BatchGetItem +// var keys []map[string]types.AttributeValue +// for i := 0; i < 25; i++ { +// keys = append(keys, map[string]types.AttributeValue{ +// "partition_key": &types.AttributeValueMemberS{Value: "benchmark-test"}, +// "sort_key": &types.AttributeValueMemberN{Value: strconv.Itoa(i)}, +// }) +// } + +// // BatchGetItem +// batchGetStart := time.Now() +// result, err := b.DbesdkClient.BatchGetItem(ctx, &dynamodb.BatchGetItemInput{ +// RequestItems: map[string]types.KeysAndAttributes{ +// tableName: {Keys: keys, ConsistentRead: aws.Bool(true)}, +// }, +// }) +// if err != nil { +// return 0, 0, fmt.Errorf("BatchGetItem failed: %w", err) +// } +// batchGetDuration := time.Since(batchGetStart).Seconds() * 1000 + +// // Verify 25 items retrieved with correct data size +// returnedItems := result.Responses[tableName] +// if len(returnedItems) != 25 { +// return 0, 0, fmt.Errorf("expected 25 items, got %d", len(returnedItems)) +// } + +// // Verify each returned item +// for i, item := range returnedItems { +// if _, ok := item["attribute1"]; !ok { +// return 0, 0, fmt.Errorf("item %d missing attribute1", i) +// } + +// // Verify attribute1 +// if attr1, ok := item["attribute1"].(*types.AttributeValueMemberM); ok { +// if dataAttr, ok := attr1.Value["data"].(*types.AttributeValueMemberB); ok { +// if !bytes.Equal(dataAttr.Value, data) { +// return 0, 0, fmt.Errorf("item %d data mismatch", i) +// } +// } +// } + +// // Verify attribute2 value +// if attr2, ok := item["attribute2"].(*types.AttributeValueMemberS); ok { +// if attr2.Value != "sign me!" { +// return 0, 0, fmt.Errorf("item %d attribute2 mismatch: got %s", i, attr2.Value) +// } +// } else { +// return 0, 0, fmt.Errorf("item %d attribute2 wrong type", i) +// } + +// // Verify :attribute3 value +// if attr3, ok := item[":attribute3"].(*types.AttributeValueMemberS); ok { +// if attr3.Value != "ignore me!" { +// return 0, 0, fmt.Errorf("item %d :attribute3 mismatch: got %s", i, attr3.Value) +// } +// } else { +// return 0, 0, fmt.Errorf("item %d :attribute3 wrong type", i) +// } +// } + +// return batchWriteDuration, batchGetDuration, nil +// } + +// 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"}, From e1c74702df309aa7f2552cb65f2bea4e4c843239 Mon Sep 17 00:00:00 2001 From: rishav-karanjit Date: Mon, 8 Sep 2025 09:04:08 -0700 Subject: [PATCH 26/33] comment not needed code --- .../benchmarks/go/benchmark/dbesdk_benchmark.go | 8 ++++---- db-esdk-performance-testing/benchmarks/go/main.go | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/db-esdk-performance-testing/benchmarks/go/benchmark/dbesdk_benchmark.go b/db-esdk-performance-testing/benchmarks/go/benchmark/dbesdk_benchmark.go index 84ce82d1d..62b5da17d 100644 --- a/db-esdk-performance-testing/benchmarks/go/benchmark/dbesdk_benchmark.go +++ b/db-esdk-performance-testing/benchmarks/go/benchmark/dbesdk_benchmark.go @@ -118,10 +118,10 @@ func (b *DBESDKBenchmark) setupDBESDK(useItemEncryptor bool) error { return err } - err = b.SetupDDB(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 diff --git a/db-esdk-performance-testing/benchmarks/go/main.go b/db-esdk-performance-testing/benchmarks/go/main.go index d31e8de8d..e676dc8fe 100644 --- a/db-esdk-performance-testing/benchmarks/go/main.go +++ b/db-esdk-performance-testing/benchmarks/go/main.go @@ -29,7 +29,7 @@ func main() { } // create dynamodb table - CreateTable(bench.DbesdkClient, bench.Config.TableName) + // CreateTable(bench.DbesdkClient, bench.Config.TableName) // Adjust config for quick test if *quick { From 2914132eac7c8f993ff3be4aa2be78b9a2972aca Mon Sep 17 00:00:00 2001 From: rishav-karanjit Date: Mon, 8 Sep 2025 09:07:05 -0700 Subject: [PATCH 27/33] auto commit --- .../benchmarks/config/test-scenarios.yaml | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/db-esdk-performance-testing/benchmarks/config/test-scenarios.yaml b/db-esdk-performance-testing/benchmarks/config/test-scenarios.yaml index 1fe002ba2..8573721fa 100644 --- a/db-esdk-performance-testing/benchmarks/config/test-scenarios.yaml +++ b/db-esdk-performance-testing/benchmarks/config/test-scenarios.yaml @@ -39,11 +39,11 @@ iterations: # Concurrency levels to test concurrency_levels: - - 1 - - 2 - - 4 - - 8 - - 16 + # - 1 + # - 2 + # - 4 + # - 8 + # - 16 # DynamoDB table name table_name: "dbesdk-performance-testing" From b4bad3757ba8a910a0547b18f5352167867c7ca1 Mon Sep 17 00:00:00 2001 From: rishav-karanjit Date: Mon, 8 Sep 2025 09:07:50 -0700 Subject: [PATCH 28/33] remove redundant files --- .../config/test-scenarios.yaml | 47 ------------------- 1 file changed, 47 deletions(-) delete mode 100644 db-esdk-performance-testing/config/test-scenarios.yaml diff --git a/db-esdk-performance-testing/config/test-scenarios.yaml b/db-esdk-performance-testing/config/test-scenarios.yaml deleted file mode 100644 index 0338f2b0c..000000000 --- a/db-esdk-performance-testing/config/test-scenarios.yaml +++ /dev/null @@ -1,47 +0,0 @@ -# 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 - - 40000000 # 40MB - -# 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" From 7ae7bf88fe031489d1ead93c02f56e71962aea27 Mon Sep 17 00:00:00 2001 From: rishav-karanjit Date: Mon, 8 Sep 2025 09:22:17 -0700 Subject: [PATCH 29/33] remove batch put and get --- .../go/benchmark/benchmark_tests.go | 102 ------------------ 1 file changed, 102 deletions(-) diff --git a/db-esdk-performance-testing/benchmarks/go/benchmark/benchmark_tests.go b/db-esdk-performance-testing/benchmarks/go/benchmark/benchmark_tests.go index db7ff0bd9..39f51f3ec 100644 --- a/db-esdk-performance-testing/benchmarks/go/benchmark/benchmark_tests.go +++ b/db-esdk-performance-testing/benchmarks/go/benchmark/benchmark_tests.go @@ -16,108 +16,6 @@ import ( // === Helper Functions === -// runBatchPutGetCycle performs a BatchWriteItem-BatchGetItem cycle with 25 items and measures performance -// func (b *DBESDKBenchmark) runBatchPutGetCycle(data []byte) (float64, float64, error) { -// ctx := context.Background() -// tableName := b.Config.TableName - -// // Create 25 write requests with same data, different sort_key -// var items []map[string]types.AttributeValue - -// for i := 0; i < 25; i++ { -// item := map[string]types.AttributeValue{ -// "partition_key": &types.AttributeValueMemberS{Value: "benchmark-test"}, -// "sort_key": &types.AttributeValueMemberN{Value: strconv.Itoa(i)}, -// "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!"}, -// } -// items = append(items, item) -// } - -// var writeRequests []types.WriteRequest -// for _, item := range items { -// writeRequests = append(writeRequests, types.WriteRequest{ -// PutRequest: &types.PutRequest{Item: item}, -// }) -// } - -// // BatchWriteItem -// batchWriteStart := time.Now() -// _, err := b.DbesdkClient.BatchWriteItem(ctx, &dynamodb.BatchWriteItemInput{ -// RequestItems: map[string][]types.WriteRequest{tableName: writeRequests}, -// }) -// if err != nil { -// return 0, 0, fmt.Errorf("BatchWriteItem failed: %w", err) -// } -// batchWriteDuration := time.Since(batchWriteStart).Seconds() * 1000 - -// // Create 25 keys for BatchGetItem -// var keys []map[string]types.AttributeValue -// for i := 0; i < 25; i++ { -// keys = append(keys, map[string]types.AttributeValue{ -// "partition_key": &types.AttributeValueMemberS{Value: "benchmark-test"}, -// "sort_key": &types.AttributeValueMemberN{Value: strconv.Itoa(i)}, -// }) -// } - -// // BatchGetItem -// batchGetStart := time.Now() -// result, err := b.DbesdkClient.BatchGetItem(ctx, &dynamodb.BatchGetItemInput{ -// RequestItems: map[string]types.KeysAndAttributes{ -// tableName: {Keys: keys, ConsistentRead: aws.Bool(true)}, -// }, -// }) -// if err != nil { -// return 0, 0, fmt.Errorf("BatchGetItem failed: %w", err) -// } -// batchGetDuration := time.Since(batchGetStart).Seconds() * 1000 - -// // Verify 25 items retrieved with correct data size -// returnedItems := result.Responses[tableName] -// if len(returnedItems) != 25 { -// return 0, 0, fmt.Errorf("expected 25 items, got %d", len(returnedItems)) -// } - -// // Verify each returned item -// for i, item := range returnedItems { -// if _, ok := item["attribute1"]; !ok { -// return 0, 0, fmt.Errorf("item %d missing attribute1", i) -// } - -// // Verify attribute1 -// if attr1, ok := item["attribute1"].(*types.AttributeValueMemberM); ok { -// if dataAttr, ok := attr1.Value["data"].(*types.AttributeValueMemberB); ok { -// if !bytes.Equal(dataAttr.Value, data) { -// return 0, 0, fmt.Errorf("item %d data mismatch", i) -// } -// } -// } - -// // Verify attribute2 value -// if attr2, ok := item["attribute2"].(*types.AttributeValueMemberS); ok { -// if attr2.Value != "sign me!" { -// return 0, 0, fmt.Errorf("item %d attribute2 mismatch: got %s", i, attr2.Value) -// } -// } else { -// return 0, 0, fmt.Errorf("item %d attribute2 wrong type", i) -// } - -// // Verify :attribute3 value -// if attr3, ok := item[":attribute3"].(*types.AttributeValueMemberS); ok { -// if attr3.Value != "ignore me!" { -// return 0, 0, fmt.Errorf("item %d :attribute3 mismatch: got %s", i, attr3.Value) -// } -// } else { -// return 0, 0, fmt.Errorf("item %d :attribute3 wrong type", i) -// } -// } - -// return batchWriteDuration, batchGetDuration, nil -// } - // 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{ From b3fb2fc789a8f9c217915a2b1b88e15babadc170 Mon Sep 17 00:00:00 2001 From: rishav-karanjit Date: Mon, 8 Sep 2025 11:42:35 -0700 Subject: [PATCH 30/33] auto commit --- .../benchmarks/go/benchmark/testRunners.go | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/db-esdk-performance-testing/benchmarks/go/benchmark/testRunners.go b/db-esdk-performance-testing/benchmarks/go/benchmark/testRunners.go index 53bb3ff9b..1eee70778 100644 --- a/db-esdk-performance-testing/benchmarks/go/benchmark/testRunners.go +++ b/db-esdk-performance-testing/benchmarks/go/benchmark/testRunners.go @@ -114,11 +114,6 @@ func (b *DBESDKBenchmark) runMemoryTest(dataSize int) (*BenchmarkResult, error) runtime.GC() time.Sleep(GCSettleTimeMs * time.Millisecond) - // Get baseline - metrics.Read(samples) - beforeHeap := samples[0].Value.Uint64() - beforeAllocs := samples[1].Value.Uint64() - // Start continuous sampling stopSampling := make(chan bool) var continuousSamples []MemorySample @@ -131,6 +126,11 @@ func (b *DBESDKBenchmark) runMemoryTest(dataSize int) (*BenchmarkResult, error) samplingMutex.Unlock() }() + // Get baseline + metrics.Read(samples) + beforeHeap := samples[0].Value.Uint64() + beforeAllocs := samples[1].Value.Uint64() + // Run operation operationStart := time.Now() _, _, err := b.runItemEncryptorCycle(data) From bc43a5eb05ac088e1b89500e3719108fd4cf105d Mon Sep 17 00:00:00 2001 From: rishav-karanjit Date: Mon, 8 Sep 2025 11:43:02 -0700 Subject: [PATCH 31/33] auto commit --- .../benchmarks/go/benchmark/testRunners.go | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/db-esdk-performance-testing/benchmarks/go/benchmark/testRunners.go b/db-esdk-performance-testing/benchmarks/go/benchmark/testRunners.go index 1eee70778..ac7ab2055 100644 --- a/db-esdk-performance-testing/benchmarks/go/benchmark/testRunners.go +++ b/db-esdk-performance-testing/benchmarks/go/benchmark/testRunners.go @@ -119,6 +119,11 @@ func (b *DBESDKBenchmark) runMemoryTest(dataSize int) (*BenchmarkResult, error) 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() @@ -126,11 +131,6 @@ func (b *DBESDKBenchmark) runMemoryTest(dataSize int) (*BenchmarkResult, error) samplingMutex.Unlock() }() - // Get baseline - metrics.Read(samples) - beforeHeap := samples[0].Value.Uint64() - beforeAllocs := samples[1].Value.Uint64() - // Run operation operationStart := time.Now() _, _, err := b.runItemEncryptorCycle(data) From de628a9e62305e4fcd908a18f88e50a8fb34c2b5 Mon Sep 17 00:00:00 2001 From: rishav-karanjit Date: Mon, 8 Sep 2025 17:20:06 -0700 Subject: [PATCH 32/33] auto commit --- .../benchmarks/config/test-scenarios.yaml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/db-esdk-performance-testing/benchmarks/config/test-scenarios.yaml b/db-esdk-performance-testing/benchmarks/config/test-scenarios.yaml index 8573721fa..36fe86e09 100644 --- a/db-esdk-performance-testing/benchmarks/config/test-scenarios.yaml +++ b/db-esdk-performance-testing/benchmarks/config/test-scenarios.yaml @@ -11,10 +11,12 @@ data_sizes: - 102400 # 100KB - 512000 # 500KB - 1048576 # 1MB + - 10000000 large: - 10485760 # 10MB - 52428800 # 50MB - - 104857600 # 100MB + - 104857600 + - 100000000 # 100MB # Quick test configuration (reduced test set for faster execution) quick_config: From aa05cd3e5fce5f9047c9ad946142a3f27a3d4991 Mon Sep 17 00:00:00 2001 From: rishav-karanjit Date: Mon, 8 Sep 2025 17:36:27 -0700 Subject: [PATCH 33/33] auto commit --- .../results/raw-data/go_results.json | 452 ++++++++++++++++++ 1 file changed, 452 insertions(+) create mode 100644 db-esdk-performance-testing/benchmarks/results/raw-data/go_results.json 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 + } + ] +}