Last active
July 7, 2021 15:32
-
-
Save komuw/c152a73a1aae766873dee1e49f7730bf to your computer and use it in GitHub Desktop.
Benchmark fdatasync vs fsync
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package main | |
import ( | |
"log" | |
"math/rand" | |
"os" | |
"syscall" | |
"testing" | |
"time" | |
"golang.org/x/sys/unix" | |
) | |
const theFile = "/tmp/theFileBenchMarkFile.txt" | |
const fSize = 50 * 1024 * 1024 // 50Mb | |
func randString(length int) []byte { | |
var source = rand.NewSource(time.Now().UnixNano()) | |
const charset = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789" | |
b := make([]byte, length) | |
for i := range b { | |
b[i] = charset[source.Int63()%int64(len(charset))] | |
} | |
return b | |
} | |
func fsync_stdlib() { | |
f, err := os.Create(theFile) | |
if err != nil { | |
log.Fatalln("unable to open file:", err) | |
} | |
_, err = f.Write(randString(fSize)) | |
if err != nil { | |
log.Fatalln("unable to write to file:", err) | |
} | |
err = f.Sync() | |
if err != nil { | |
log.Fatalln("unable to Sync file:", err) | |
} | |
err = f.Close() | |
if err != nil { | |
log.Fatalln("unable to Close file:", err) | |
} | |
} | |
func fsync_x_sys() { | |
f, err := os.Create(theFile) | |
if err != nil { | |
log.Fatalln("unable to open file:", err) | |
} | |
_, err = f.Write(randString(fSize)) | |
if err != nil { | |
log.Fatalln("unable to write to file:", err) | |
} | |
err = unix.Fsync(int(f.Fd())) | |
if err != nil { | |
log.Fatalln("unable to Sync file:", err) | |
} | |
err = f.Close() | |
if err != nil { | |
log.Fatalln("unable to Close file:", err) | |
} | |
} | |
func fdatasync_stdlib() { | |
f, err := os.Create(theFile) | |
if err != nil { | |
log.Fatalln("unable to open file:", err) | |
} | |
_, err = f.Write(randString(fSize)) | |
if err != nil { | |
log.Fatalln("unable to write to file:", err) | |
} | |
// fdatasync() [...] does not flush modified metadata unless that metadata is needed in order to allow a subsequent data retrieval to be correctly handled. [...] | |
// On the other hand, a change to the file size (st_size, as made by say ftruncate(2)), would require a metadata flush. | |
// | |
// Note: sync of file does not also sync its directory. | |
// The directory needs to also be synced | |
err = syscall.Fdatasync(int(f.Fd())) | |
if err != nil { | |
log.Fatalln("unable to Fdatasync file:", err) | |
} | |
err = f.Close() | |
if err != nil { | |
log.Fatalln("unable to Close file:", err) | |
} | |
} | |
func fdatasync_x_sys() { | |
f, err := os.Create(theFile) | |
if err != nil { | |
log.Fatalln("unable to open file:", err) | |
} | |
_, err = f.Write(randString(fSize)) | |
if err != nil { | |
log.Fatalln("unable to write to file:", err) | |
} | |
err = unix.Fdatasync(int(f.Fd())) | |
if err != nil { | |
log.Fatalln("unable to Fdatasync file:", err) | |
} | |
err = f.Close() | |
if err != nil { | |
log.Fatalln("unable to Close file:", err) | |
} | |
} | |
func removeFile() { | |
_ = os.Remove(theFile) | |
} | |
func BenchmarkFSync_stdlib(b *testing.B) { | |
removeFile() | |
b.ResetTimer() | |
for i := 0; i < b.N; i++ { | |
fsync_stdlib() | |
} | |
} | |
func BenchmarkFSync_x_sys(b *testing.B) { | |
removeFile() | |
b.ResetTimer() | |
for i := 0; i < b.N; i++ { | |
fsync_x_sys() | |
} | |
} | |
func BenchmarkFDataSync_stdlib(b *testing.B) { | |
removeFile() | |
b.ResetTimer() | |
for i := 0; i < b.N; i++ { | |
fdatasync_stdlib() | |
} | |
} | |
func BenchmarkFDataSync_x_sys(b *testing.B) { | |
removeFile() | |
b.ResetTimer() | |
for i := 0; i < b.N; i++ { | |
fdatasync_x_sys() | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
go test -timeout 10m -v -race -cover -bench=. -run=XXX ./...