Commit 48ea9ea7 authored by Kirill Smelkov's avatar Kirill Smelkov

.

parent dcdba0e3
...@@ -4,13 +4,14 @@ import ( ...@@ -4,13 +4,14 @@ import (
"crypto/rand" "crypto/rand"
"fmt" "fmt"
"os" "os"
"syscall"
"testing" "testing"
) )
// xpread is pread(2) but aborts on an error or when fewer bytes was read // xpread is pread(2) but aborts on an error or when fewer bytes was read
func xpread(f *os.File, buf []byte, offset int64) { func xpread(fd int, buf []byte, offset int64) {
n, err := f.ReadAt(buf, offset) n, err := syscall.Pread(fd, buf, offset)
if err != nil { if err != nil {
panic(err) panic(err)
} }
...@@ -19,38 +20,77 @@ func xpread(f *os.File, buf []byte, offset int64) { ...@@ -19,38 +20,77 @@ func xpread(f *os.File, buf []byte, offset int64) {
} }
} }
// BenchmarkPread1 benchmarks pread syscall when reading 1 byte from a file on tmpfs // xreadat is ReadAt but aborts on an error or when fewer bytes was read
func BenchmarkPread1(b *testing.B) { func xreadat(f *os.File, buf []byte, offset int64) {
n, err := f.ReadAt(buf, offset)
if err != nil {
panic(err)
}
if n != len(buf) {
panic(fmt.Errorf("readat(%v) -> %v", len(buf), n))
}
}
// setupXdat4K setups /dev/shm/x.dat with 4K content
func setupXdat4K(t testing.TB) *os.File {
// setup 4K file on a tmpfs // setup 4K file on a tmpfs
f, err := os.Create("/dev/shm/x.dat") f, err := os.Create("/dev/shm/x.dat")
if err != nil { if err != nil {
b.Fatal(err) t.Fatal(err)
} }
buf4K := make([]byte, 4096) buf4K := make([]byte, 4096)
_, err = rand.Read(buf4K) _, err = rand.Read(buf4K)
if err != nil { if err != nil {
// rand promises n = len(buf) <=> err == nil // rand promises n = len(buf) <=> err == nil
b.Fatal(err) t.Fatal(err)
} }
_, err = f.Write(buf4K) _, err = f.Write(buf4K)
if err != nil { if err != nil {
b.Fatal(err) t.Fatal(err)
}
return f
}
// BenchmarkReadAt benchmarks os.File.ReadAt when reading 1 byte from a file on tmpfs
func BenchmarkReadAt1(b *testing.B) {
f := setupXdat4K(b)
buf1B := make([]byte, 1)
// warm up
xreadat(f, buf1B, 0)
b.ResetTimer()
for i := 0; i < b.N; i++ {
xreadat(f, buf1B, 0)
}
b.StopTimer()
err := f.Close()
if err != nil {
b.Fatal(f)
} }
}
// BenchmarkPread1 benchmarks pread syscall when reading 1 byte from a file on tmpfs
func BenchmarkPread1(b *testing.B) {
f := setupXdat4K(b)
fd := int(f.Fd()) // syscall wants fd as int, not uintptr
buf1B := make([]byte, 1) buf1B := make([]byte, 1)
// warm up // warm up
xpread(f, buf1B, 0) xpread(fd, buf1B, 0)
b.ResetTimer() b.ResetTimer()
for i := 0; i < b.N; i++ { for i := 0; i < b.N; i++ {
xpread(f, buf1B, 0) xpread(fd, buf1B, 0)
} }
b.StopTimer() b.StopTimer()
err = f.Close() err := f.Close()
if err != nil { if err != nil {
b.Fatal(f) b.Fatal(f)
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment