Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- package main
- /*
- test modes for sending file to socket.
- requires test_file.txt in a directory, or pass -file argument.
- Results go 1.4 linux x86_64
- $ for i in 0 1 2 3 ; do ./test_copy -mode=$i ; done
- 0 - io.CopyN(net.TCPConn, os.File)
- real 0.772
- user 0.012
- sys 0.766
- 1 - mmap+io.CopyN(net.TCPConn, buffer)
- real 1.236
- user 0.428
- sys 0.812
- 2 - io.CopyN(net.TCPConn, io.LimitReader(os.File))
- real 1.339
- user 0.112
- sys 1.232
- 3 - mmap+io.CopyN(net.TCPConn, io.LimitReader(buffer))
- real 1.183
- user 0.380
- sys 0.807
- Results go 1.5-dev linux x86_64
- $ for i in 0 1 2 3 ; do ./test_copy -mode=$i ; done
- 0 - io.CopyN(net.TCPConn, os.File)
- real 0.785
- user 0.032
- sys 0.772
- 1 - mmap+io.CopyN(net.TCPConn, buffer)
- real 1.252
- user 0.450
- sys 0.807
- 2 - io.CopyN(net.TCPConn, io.LimitReader(os.File))
- real 1.420
- user 0.132
- sys 1.292
- 3 - mmap+io.CopyN(net.TCPConn, io.LimitReader(buffer))
- real 1.207
- user 0.397
- sys 0.813
- Result for go 1.5-dev if https://go-review.googlesource.com/#/c/7893/ accepted
- $ for i in 0 1 2 3 ; do ./test_copy -mode=$i ; done
- 0 - io.CopyN(net.TCPConn, os.File)
- real 0.708
- user 0.016
- sys 0.698
- 1 - mmap+io.CopyN(net.TCPConn, buffer)
- real 0.662
- user 0.057
- sys 1.046
- 2 - io.CopyN(net.TCPConn, io.LimitReader(os.File))
- real 0.539
- user 0.029
- sys 0.735
- 3 - mmap+io.CopyN(net.TCPConn, io.LimitReader(buffer))
- real 0.653
- user 0.067
- sys 1.019
- */
- import (
- "flag"
- "fmt"
- "io"
- "net"
- "os"
- "runtime"
- "syscall"
- "time"
- )
- var modeNames = []string{
- "0 - io.CopyN(net.TCPConn, os.File)",
- "1 - mmap+io.CopyN(net.TCPConn, buffer)",
- "2 - io.CopyN(net.TCPConn, io.LimitReader(os.File))",
- "3 - mmap+io.CopyN(net.TCPConn, io.LimitReader(buffer))"}
- var gomaxprocs = flag.Int("procs", 1, "GOMAXPROCS")
- var mode = flag.Int("mode", 0, fmt.Sprintf("%s\n%s\n%s\n%s", modeNames[0], modeNames[1], modeNames[2], modeNames[3]))
- var file = flag.String("file", "test_file.txt", "file to read")
- var n = flag.Int("cycles", 400, "number of cycles")
- var mmap = flag.String("mmap", "private", "private or shared mmaping")
- // mode == 0
- func sendfile(sock *net.TCPConn, fl *os.File) {
- for i := 0; i < *n; i++ {
- _, err := fl.Seek(0, os.SEEK_SET)
- if err != nil {
- panic(err)
- }
- _, err = io.CopyN(sock, fl, 10*1024*1024)
- if err != nil {
- panic(err)
- }
- }
- }
- // mode == 2
- func mode2(sock *net.TCPConn, fl *os.File) {
- for i := 0; i < *n; i++ {
- _, err := fl.Seek(0, os.SEEK_SET)
- if err != nil {
- panic(err)
- }
- limited := io.LimitReader(fl, 20*1024*1024)
- _, err = io.CopyN(sock, limited, 10*1024*1024)
- if err != nil {
- panic(err)
- }
- }
- }
- type tinyReader struct {
- b []byte
- pos int
- }
- func (r *tinyReader) Read(b []byte) (n int, err error) {
- if r.pos == len(r.b) {
- return 0, io.EOF
- }
- n = copy(b, r.b[r.pos:])
- r.pos += n
- return
- }
- func (r *tinyReader) WriteTo(w io.Writer) (n int64, err error) {
- if r.pos == len(r.b) {
- return 0, io.EOF
- }
- var in int
- in, err = w.Write(r.b[r.pos:])
- n = int64(in)
- r.pos += in
- return
- }
- func (r *tinyReader) WriteToN(w io.Writer, sz int64) (n int64, err error) {
- if r.pos == len(r.b) {
- return 0, io.EOF
- }
- if int64(r.pos)+sz > int64(len(r.b)) {
- sz = int64(len(r.b) - r.pos)
- }
- var in int
- in, err = w.Write(r.b[r.pos : r.pos+int(sz)])
- n = int64(in)
- r.pos += in
- return
- }
- // mode == 1
- func mapcopy(sock *net.TCPConn, fl *os.File) {
- stat, err := fl.Stat()
- if err != nil {
- panic(err)
- }
- var slice []byte
- if *mmap == "shared" {
- slice, err = syscall.Mmap(int(fl.Fd()), 0, int(stat.Size()), syscall.PROT_READ, syscall.MAP_SHARED)
- } else {
- slice, err = syscall.Mmap(int(fl.Fd()), 0, int(stat.Size()), syscall.PROT_READ, syscall.MAP_PRIVATE)
- }
- if err != nil {
- panic(err)
- }
- for i := 0; i < *n; i++ {
- buf := tinyReader{b: slice}
- _, err := io.CopyN(sock, &buf, 10*1024*1024)
- if err != nil {
- panic(err)
- }
- }
- syscall.Munmap(slice)
- sock.Close()
- }
- // mode == 3
- func mapcopy2(sock *net.TCPConn, fl *os.File) {
- stat, err := fl.Stat()
- if err != nil {
- panic(err)
- }
- var slice []byte
- if *mmap == "shared" {
- slice, err = syscall.Mmap(int(fl.Fd()), 0, int(stat.Size()), syscall.PROT_READ, syscall.MAP_SHARED)
- } else {
- slice, err = syscall.Mmap(int(fl.Fd()), 0, int(stat.Size()), syscall.PROT_READ, syscall.MAP_PRIVATE)
- }
- if err != nil {
- panic(err)
- }
- for i := 0; i < *n; i++ {
- buf := tinyReader{b: slice}
- limited := io.LimitReader(&buf, 20*1024*1024)
- _, err := io.CopyN(sock, limited, 10*1024*1024)
- if err != nil {
- panic(err)
- }
- }
- syscall.Munmap(slice)
- sock.Close()
- }
- func n2s(t int64) float64 {
- return float64(t) / 1e9
- }
- func main() {
- start := time.Now()
- flag.Parse()
- if *gomaxprocs > 1 {
- runtime.GOMAXPROCS(*gomaxprocs)
- }
- if *mode >= len(modeNames) {
- flag.Usage()
- os.Exit(1)
- }
- fmt.Println(modeNames[*mode])
- fl, err := os.Open("test_file.txt")
- if err != nil {
- panic(err)
- }
- addr := net.TCPAddr{IP: net.ParseIP("127.0.0.1"), Port: 8213}
- listen, err := net.ListenTCP("tcp", &addr)
- if err != nil {
- panic(err)
- }
- go func() {
- cl, err := net.DialTCP("tcp", nil, &addr)
- if err != nil {
- panic(err)
- }
- switch *mode {
- case 0:
- sendfile(cl, fl)
- case 1:
- mapcopy(cl, fl)
- case 2:
- mode2(cl, fl)
- case 3:
- mapcopy2(cl, fl)
- }
- cl.Close()
- fl.Close()
- }()
- sock, err := listen.Accept()
- if err != nil {
- panic(err)
- }
- buf := [256 * 1024]byte{}
- for err == nil {
- _, err = sock.Read(buf[:])
- }
- if err != io.EOF {
- panic(err)
- }
- lasts := time.Now().Sub(start)
- sock.Close()
- listen.Close()
- var rusage syscall.Rusage
- err = syscall.Getrusage(syscall.RUSAGE_SELF, &rusage)
- if err != nil {
- panic(err)
- }
- fmt.Printf("real\t%4.3f\nuser\t%4.3f\nsys\t%4.3f\n",
- n2s(int64(lasts)),
- n2s(rusage.Utime.Nano()),
- n2s(rusage.Stime.Nano()))
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement