batman
Brijesh Wawdhane ops@brijesh.dev
Sun, 23 Mar 2025 21:06:18 +0530
4 files changed,
89 insertions(+),
0 deletions(-)
A
go.mod
@@ -0,0 +1,10 @@
+module benchmark-api + +go 1.23.5 + +require ( + github.com/google/uuid v1.6.0 + golang.org/x/crypto v0.36.0 +) + +require golang.org/x/sys v0.31.0 // indirect
A
go.sum
@@ -0,0 +1,6 @@
+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= +golang.org/x/crypto v0.36.0 h1:AnAEvhDddvBdpY+uR+MyHmuZzzNqXSe/GvuDeob5L34= +golang.org/x/crypto v0.36.0/go.mod h1:Y4J0ReaxCR1IMaabaSMugxJES1EpwhBHhv2bDHklZvc= +golang.org/x/sys v0.31.0 h1:ioabZlmFYtWhL+TRYpcnNlLwhyxaM9kWTDEmfnprqik= +golang.org/x/sys v0.31.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k=
A
main.go
@@ -0,0 +1,55 @@
+package main + +import ( + "crypto/rand" + "encoding/base64" + "fmt" + "log" + "net/http" + "runtime" + + "github.com/google/uuid" + "golang.org/x/crypto/argon2" +) + +func main() { + // Ensure we use all available cores for maximum performance + numCPU := runtime.NumCPU() + runtime.GOMAXPROCS(numCPU) + log.Printf("Server starting with %d CPU cores available", numCPU) + + // Setup routes + http.HandleFunc("/", benchmarkHandler) + + // Start server + log.Println("Benchmark API server listening on :5001") + if err := http.ListenAndServe(":5001", nil); err != nil { + log.Fatalf("Server failed to start: %v", err) + } +} + +func benchmarkHandler(w http.ResponseWriter, r *http.Request) { + // Generate a new UUID for this request + id := uuid.New() + + // Generate a random salt + salt := make([]byte, 16) + if _, err := rand.Read(salt); err != nil { + http.Error(w, "Failed to generate salt", http.StatusInternalServerError) + return + } + + // Run expensive Argon2id hashing operation + // Parameters chosen to be computationally expensive + // - time: 3 iterations (higher values increase computation time) + // - memory: 64 MB (higher values increase memory usage) + // - threads: 4 (adjust based on testing, too high might cause contention) + // - key length: 32 bytes + hash := argon2.IDKey([]byte(id.String()), salt, 3, 64*1024, 4, 32) + hashStr := base64.StdEncoding.EncodeToString(hash) + + // Return the result + w.Header().Set("Content-Type", "application/json") + w.WriteHeader(http.StatusOK) + fmt.Fprintf(w, `{"uuid":"%s","hash":"%s"}`, id, hashStr) +}
A
run-benchmark.sh
@@ -0,0 +1,18 @@
+#!/bin/bash + +# Run benchmark and save output +hey -n 1000 -c 50 -m GET http://localhost:5001/ >benchmark_results.txt + +# Extract metrics (adjust grep patterns if needed) +REQUESTS_PER_SEC=$(grep "Requests/sec:" benchmark_results.txt | awk '{print $2}') +AVG_RESPONSE=$(grep "Average:" benchmark_results.txt | awk '{print $2}') + +# Calculate score +SCORE=$(echo "scale=2; ($REQUESTS_PER_SEC / $AVG_RESPONSE) * 100" | bc) + +# Output results +echo "===== BENCHMARK RESULTS =====" +echo "Requests/sec: $REQUESTS_PER_SEC" +echo "Average Response: $AVG_RESPONSE seconds" +echo "BENCHMARK SCORE: $SCORE" +echo "============================"