Skip to content

Instantly share code, notes, and snippets.

@y1r

y1r/benchmark.sh Secret

Last active December 26, 2021 16:13
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save y1r/dc9ea1d36628c043c5fa7850397f1ff9 to your computer and use it in GitHub Desktop.
Save y1r/dc9ea1d36628c043c5fa7850397f1ff9 to your computer and use it in GitHub Desktop.
sendfile(2)をGoから使う
#!/bin/bash
FILENAME=test.img
function run_experiment() {
listener="$1"
handler="$2"
./sendfile-benchmark -filepath $FILENAME -listener "$listener" -handler "$handler" &
pid=$!
sleep 3
LOGNAME="${listener}-${handler}.log"
rm -rf "$LOGNAME"
for (( i = 0; i < 10; i++ )); do
if [[ $listener = "unix" ]]; then
curl --unix-socket ./sock localhost/ -o /dev/null -w "%{speed_download}\n" | tee -a "$LOGNAME"
else
curl localhost:12345 -o /dev/null -w "%{speed_download}\n" | tee -a "$LOGNAME"
fi
done
kill -SIGTERM $pid
wait
}
FILESIZE=$((1024 * 1024 * 1024))
FILESIZE_IN_MB=$((FILESIZE / 1024 / 1024))
dd if=/dev/zero of=$FILENAME bs=1M count=$FILESIZE_IN_MB
go build .
for listener in "tcp" "unix"; do
run_experiment "$listener" "serve-content"
for length in "with" "without"; do
for abstraction in "with" "without"; do
run_experiment "$listener" "${length}-length-${abstraction}-abstraction"
done
done
done
package main
import (
"flag"
"io"
"log"
"net"
"net/http"
"os"
"strconv"
"time"
)
func main() {
filepath := flag.String("filepath", "", "Specify a path to file served")
listener := flag.String("listener", "", "Specify a method to listen (tcp, unix)")
handler := flag.String("handler", "", "Specify a method to handle (serve-content, with/without-length-with/without-length")
flag.Parse()
if *filepath == "" {
log.Fatal("Please specify filepath")
}
var listenerObj net.Listener
if *listener == "tcp" {
listenerObj = tcpListener()
} else if *listener == "unix" {
listenerObj = unixListener()
} else {
log.Fatalf("Not supported listener: %s\n", *listener)
}
var handlerObj http.Handler
if *handler == "serve-content" {
handlerObj = serveContentHandler(*filepath)
} else if *handler == "with-length-with-abstraction" {
handlerObj = serveImpl(*filepath, true, true)
} else if *handler == "with-length-without-abstraction" {
handlerObj = serveImpl(*filepath, true, false)
} else if *handler == "without-length-with-abstraction" {
handlerObj = serveImpl(*filepath, false, true)
} else if *handler == "without-length-without-abstraction" {
handlerObj = serveImpl(*filepath, false, false)
} else {
log.Fatalf("Not supported handler: %s\n", *handler)
}
http.Serve(listenerObj, handlerObj)
}
func tcpListener() net.Listener {
listener, err := net.Listen("tcp", "localhost:12345")
if err != nil {
log.Fatalf("error on tcpListener: %v\n", err)
}
return listener
}
func unixListener() net.Listener {
os.Remove("./sock")
socket, _ := net.Listen("unix", "./sock")
return socket
}
func serveContentHandler(file string) http.Handler {
mux := http.NewServeMux()
mux.HandleFunc("/", func(writer http.ResponseWriter, request *http.Request) {
http.ServeFile(writer, request, file)
})
return mux
}
func serveImpl(file string, withLength bool, withAbstraction bool) http.Handler {
mux := http.NewServeMux()
mux.HandleFunc("/", func(writer http.ResponseWriter, request *http.Request) {
fileObj, err := os.Open(file)
if err != nil {
log.Fatalf("File %s does not exist", file)
}
defer fileObj.Close()
if withLength {
fileinfo, err := fileObj.Stat()
if err != nil {
log.Fatalf("Failed to get %s info", file)
}
writer.Header().Set("Content-Length", strconv.FormatInt(fileinfo.Size(), 10))
}
var w io.Writer
if withAbstraction {
w = abstractedWriter{underlying: writer}
} else {
w = writer
}
start := time.Now()
written, _ := io.Copy(w, fileObj)
elapsed := time.Now().Sub(start)
log.Printf("%f MB/s\n", float64(written)/1024/1024/elapsed.Seconds())
})
return mux
}
type abstractedWriter struct {
underlying io.Writer
}
func (w abstractedWriter) Write(p []byte) (n int, err error) {
return w.underlying.Write(p)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment