From 1ea4d58d6ecaf9a8cad7d1f4d0509e0590ea441e Mon Sep 17 00:00:00 2001 From: Folkert Date: Tue, 5 Mar 2024 10:07:17 +0100 Subject: [PATCH] add go benchmarks --- benchmarks/go/csv-svg-path.go | 89 ++++++++++++++++++++++++++++ benchmarks/go/varying-allocations.go | 68 +++++++++++++++++++++ 2 files changed, 157 insertions(+) create mode 100644 benchmarks/go/csv-svg-path.go create mode 100644 benchmarks/go/varying-allocations.go diff --git a/benchmarks/go/csv-svg-path.go b/benchmarks/go/csv-svg-path.go new file mode 100644 index 0000000..52c6b7a --- /dev/null +++ b/benchmarks/go/csv-svg-path.go @@ -0,0 +1,89 @@ +package main + +import ( + "fmt" + "net/http" + "io" + "strings" + "strconv" +) + +import _ "embed" + +//go:embed static/Cargo.toml +var cargoToml string + +var workerCount = 2 +var workerPool chan struct{} + +func main() { + // Create a buffered channel to limit the number of concurrent worker threads + workerPool = make(chan struct{}, workerCount) + + // Handle requests using a single IO thread + http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) { + // Acquire a worker thread from the pool + workerPool <- struct{}{} + + // Handle the request in a goroutine + { + // Ensure the worker is released back to the pool when done + defer func() { + <-workerPool + }() + + // Handle the actual request (in this case, just returning "Hello, World!") + handleRequest(w, r) + } + }) + + // Start the web server on port 8080 + fmt.Println("Server listening on :8080") + http.ListenAndServe(":8080", nil) +} + +func handleRequest(w http.ResponseWriter, r *http.Request) { + body, err := io.ReadAll(r.Body) + if err != nil { + http.Error(w, "Error reading request body", http.StatusInternalServerError) + return + } + + pathString, err := generateSVGPath(string(body)) + if err != nil { + http.Error(w, "Error processing request body", http.StatusBadRequest) + return + } + + response := fmt.Sprintf(` + + +`, pathString) + + _, _ = w.Write([]byte(response)) +} + +func generateSVGPath(requestBody string) (string, error) { + lines := strings.Split(requestBody, "\n") + + var pathString strings.Builder + pathString.WriteString("M 0 0 L") + + for _, line := range lines { + parts := strings.SplitN(line, ", ", 2) + if len(parts) != 2 { + continue + } + + x, errX := strconv.Atoi(parts[0]) + y, errY := strconv.Atoi(parts[1]) + + if errX != nil || errY != nil { + return "", fmt.Errorf("invalid input format") + } + + _, _ = fmt.Fprintf(&pathString, " %d %d", x, y) + } + + return pathString.String(), nil +} diff --git a/benchmarks/go/varying-allocations.go b/benchmarks/go/varying-allocations.go new file mode 100644 index 0000000..3582d9a --- /dev/null +++ b/benchmarks/go/varying-allocations.go @@ -0,0 +1,68 @@ +package main + +import ( + "fmt" + "net/http" + "strings" + "strconv" +) + +var workerCount = 2 +var workerPool chan struct{} + +func main() { + // Create a buffered channel to limit the number of concurrent worker threads + workerPool = make(chan struct{}, workerCount) + + // Handle requests using a single IO thread + http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) { + // Acquire a worker thread from the pool + workerPool <- struct{}{} + + // Handle the request in a goroutine + { + // Ensure the worker is released back to the pool when done + defer func() { + <-workerPool + }() + + // Handle the actual request (in this case, just returning "Hello, World!") + handleRequest(w, r) + } + }) + + // Start the web server on port 8080 + fmt.Println("Server listening on :8080") + http.ListenAndServe(":8080", nil) +} + +func handleRequest(w http.ResponseWriter, r *http.Request) { + // Get the path from the URL + path := r.URL.Path + + // Split the path using "/" + parts := strings.Split(path, "/") + + // The last part of the path should be the number + if len(parts) > 0 { + lastPart := parts[len(parts)-1] + + // Convert the last part to an integer + capacity, err := strconv.Atoi(lastPart) + if err != nil { + http.Error(w, "Invalid ID", http.StatusBadRequest) + return + } + + // Allocate an array of N bytes using make + byteArray := make([]byte, capacity) + + for i := range byteArray { + byteArray[i] = 0xAA + } + + _ = byteArray; + } else { + http.Error(w, "Invalid URL", http.StatusBadRequest) + } +}