Source file src/net/sendfile_linux_test.go

     1  // Copyright 2022 The Go Authors. All rights reserved.
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4  
     5  //go:build linux
     6  
     7  package net
     8  
     9  import (
    10  	"io"
    11  	"os"
    12  	"strconv"
    13  	"testing"
    14  )
    15  
    16  func BenchmarkSendFile(b *testing.B) {
    17  	b.Run("file-to-tcp", func(b *testing.B) { benchmarkSendFile(b, "tcp") })
    18  	b.Run("file-to-unix", func(b *testing.B) { benchmarkSendFile(b, "unix") })
    19  }
    20  
    21  func benchmarkSendFile(b *testing.B, proto string) {
    22  	for i := 0; i <= 10; i++ {
    23  		size := 1 << (i + 10)
    24  		bench := sendFileBench{
    25  			proto:     proto,
    26  			chunkSize: size,
    27  		}
    28  		b.Run(strconv.Itoa(size), bench.benchSendFile)
    29  	}
    30  }
    31  
    32  type sendFileBench struct {
    33  	proto     string
    34  	chunkSize int
    35  }
    36  
    37  func (bench sendFileBench) benchSendFile(b *testing.B) {
    38  	fileSize := b.N * bench.chunkSize
    39  	f := createTempFile(b, fileSize)
    40  
    41  	client, server := spliceTestSocketPair(b, bench.proto)
    42  	defer server.Close()
    43  
    44  	cleanUp, err := startSpliceClient(client, "r", bench.chunkSize, fileSize)
    45  	if err != nil {
    46  		client.Close()
    47  		b.Fatal(err)
    48  	}
    49  	defer cleanUp()
    50  
    51  	b.ReportAllocs()
    52  	b.SetBytes(int64(bench.chunkSize))
    53  	b.ResetTimer()
    54  
    55  	// Data go from file to socket via sendfile(2).
    56  	sent, err := io.Copy(server, f)
    57  	if err != nil {
    58  		b.Fatalf("failed to copy data with sendfile, error: %v", err)
    59  	}
    60  	if sent != int64(fileSize) {
    61  		b.Fatalf("bytes sent mismatch, got: %d, want: %d", sent, fileSize)
    62  	}
    63  }
    64  
    65  func createTempFile(b *testing.B, size int) *os.File {
    66  	f, err := os.CreateTemp(b.TempDir(), "linux-sendfile-bench")
    67  	if err != nil {
    68  		b.Fatalf("failed to create temporary file: %v", err)
    69  	}
    70  	b.Cleanup(func() {
    71  		f.Close()
    72  	})
    73  
    74  	data := make([]byte, size)
    75  	if _, err := f.Write(data); err != nil {
    76  		b.Fatalf("failed to create and feed the file: %v", err)
    77  	}
    78  	if err := f.Sync(); err != nil {
    79  		b.Fatalf("failed to save the file: %v", err)
    80  	}
    81  	if _, err := f.Seek(0, io.SeekStart); err != nil {
    82  		b.Fatalf("failed to rewind the file: %v", err)
    83  	}
    84  
    85  	return f
    86  }
    87  

View as plain text