Advertisement
funny_falcon

test_copy.go

Apr 1st, 2015
478
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Go 5.82 KB | None | 0 0
  1. package main
  2.  
  3. /*
  4. test modes for sending file to socket.
  5. requires test_file.txt in a directory, or pass -file argument.
  6.  
  7. Results go 1.4 linux x86_64
  8. $ for i in 0 1 2 3 ; do ./test_copy -mode=$i ; done
  9.  
  10. 0 - io.CopyN(net.TCPConn, os.File)
  11. real    0.772
  12. user    0.012
  13. sys 0.766
  14. 1 - mmap+io.CopyN(net.TCPConn, buffer)
  15. real    1.236
  16. user    0.428
  17. sys 0.812
  18. 2 - io.CopyN(net.TCPConn, io.LimitReader(os.File))
  19. real    1.339
  20. user    0.112
  21. sys 1.232
  22. 3 - mmap+io.CopyN(net.TCPConn, io.LimitReader(buffer))
  23. real    1.183
  24. user    0.380
  25. sys 0.807
  26.  
  27. Results go 1.5-dev linux x86_64
  28. $ for i in 0 1 2 3 ; do ./test_copy -mode=$i ; done
  29. 0 - io.CopyN(net.TCPConn, os.File)
  30. real    0.785
  31. user    0.032
  32. sys 0.772
  33. 1 - mmap+io.CopyN(net.TCPConn, buffer)
  34. real    1.252
  35. user    0.450
  36. sys 0.807
  37. 2 - io.CopyN(net.TCPConn, io.LimitReader(os.File))
  38. real    1.420
  39. user    0.132
  40. sys 1.292
  41. 3 - mmap+io.CopyN(net.TCPConn, io.LimitReader(buffer))
  42. real    1.207
  43. user    0.397
  44. sys 0.813
  45.  
  46. Result for go 1.5-dev if https://go-review.googlesource.com/#/c/7893/ accepted
  47. $ for i in 0 1 2 3 ; do ./test_copy -mode=$i ; done
  48. 0 - io.CopyN(net.TCPConn, os.File)
  49. real    0.708
  50. user    0.016
  51. sys 0.698
  52. 1 - mmap+io.CopyN(net.TCPConn, buffer)
  53. real    0.662
  54. user    0.057
  55. sys 1.046
  56. 2 - io.CopyN(net.TCPConn, io.LimitReader(os.File))
  57. real    0.539
  58. user    0.029
  59. sys 0.735
  60. 3 - mmap+io.CopyN(net.TCPConn, io.LimitReader(buffer))
  61. real    0.653
  62. user    0.067
  63. sys 1.019
  64. */
  65.  
  66. import (
  67.     "flag"
  68.     "fmt"
  69.     "io"
  70.     "net"
  71.     "os"
  72.     "runtime"
  73.     "syscall"
  74.     "time"
  75. )
  76.  
  77. var modeNames = []string{
  78.     "0 - io.CopyN(net.TCPConn, os.File)",
  79.     "1 - mmap+io.CopyN(net.TCPConn, buffer)",
  80.     "2 - io.CopyN(net.TCPConn, io.LimitReader(os.File))",
  81.     "3 - mmap+io.CopyN(net.TCPConn, io.LimitReader(buffer))"}
  82. var gomaxprocs = flag.Int("procs", 1, "GOMAXPROCS")
  83. var mode = flag.Int("mode", 0, fmt.Sprintf("%s\n%s\n%s\n%s", modeNames[0], modeNames[1], modeNames[2], modeNames[3]))
  84. var file = flag.String("file", "test_file.txt", "file to read")
  85. var n = flag.Int("cycles", 400, "number of cycles")
  86. var mmap = flag.String("mmap", "private", "private or shared mmaping")
  87.  
  88. // mode == 0
  89. func sendfile(sock *net.TCPConn, fl *os.File) {
  90.     for i := 0; i < *n; i++ {
  91.         _, err := fl.Seek(0, os.SEEK_SET)
  92.         if err != nil {
  93.             panic(err)
  94.         }
  95.         _, err = io.CopyN(sock, fl, 10*1024*1024)
  96.         if err != nil {
  97.             panic(err)
  98.         }
  99.     }
  100. }
  101.  
  102. // mode == 2
  103. func mode2(sock *net.TCPConn, fl *os.File) {
  104.     for i := 0; i < *n; i++ {
  105.         _, err := fl.Seek(0, os.SEEK_SET)
  106.         if err != nil {
  107.             panic(err)
  108.         }
  109.         limited := io.LimitReader(fl, 20*1024*1024)
  110.         _, err = io.CopyN(sock, limited, 10*1024*1024)
  111.         if err != nil {
  112.             panic(err)
  113.         }
  114.     }
  115. }
  116.  
  117. type tinyReader struct {
  118.     b   []byte
  119.     pos int
  120. }
  121.  
  122. func (r *tinyReader) Read(b []byte) (n int, err error) {
  123.     if r.pos == len(r.b) {
  124.         return 0, io.EOF
  125.     }
  126.     n = copy(b, r.b[r.pos:])
  127.     r.pos += n
  128.     return
  129. }
  130.  
  131. func (r *tinyReader) WriteTo(w io.Writer) (n int64, err error) {
  132.     if r.pos == len(r.b) {
  133.         return 0, io.EOF
  134.     }
  135.     var in int
  136.     in, err = w.Write(r.b[r.pos:])
  137.     n = int64(in)
  138.     r.pos += in
  139.     return
  140. }
  141.  
  142. func (r *tinyReader) WriteToN(w io.Writer, sz int64) (n int64, err error) {
  143.     if r.pos == len(r.b) {
  144.         return 0, io.EOF
  145.     }
  146.     if int64(r.pos)+sz > int64(len(r.b)) {
  147.         sz = int64(len(r.b) - r.pos)
  148.     }
  149.     var in int
  150.     in, err = w.Write(r.b[r.pos : r.pos+int(sz)])
  151.     n = int64(in)
  152.     r.pos += in
  153.     return
  154. }
  155.  
  156. // mode == 1
  157. func mapcopy(sock *net.TCPConn, fl *os.File) {
  158.     stat, err := fl.Stat()
  159.     if err != nil {
  160.         panic(err)
  161.     }
  162.     var slice []byte
  163.     if *mmap == "shared" {
  164.         slice, err = syscall.Mmap(int(fl.Fd()), 0, int(stat.Size()), syscall.PROT_READ, syscall.MAP_SHARED)
  165.     } else {
  166.         slice, err = syscall.Mmap(int(fl.Fd()), 0, int(stat.Size()), syscall.PROT_READ, syscall.MAP_PRIVATE)
  167.     }
  168.     if err != nil {
  169.         panic(err)
  170.     }
  171.     for i := 0; i < *n; i++ {
  172.         buf := tinyReader{b: slice}
  173.         _, err := io.CopyN(sock, &buf, 10*1024*1024)
  174.         if err != nil {
  175.             panic(err)
  176.         }
  177.     }
  178.     syscall.Munmap(slice)
  179.     sock.Close()
  180. }
  181.  
  182. // mode == 3
  183. func mapcopy2(sock *net.TCPConn, fl *os.File) {
  184.     stat, err := fl.Stat()
  185.     if err != nil {
  186.         panic(err)
  187.     }
  188.     var slice []byte
  189.     if *mmap == "shared" {
  190.         slice, err = syscall.Mmap(int(fl.Fd()), 0, int(stat.Size()), syscall.PROT_READ, syscall.MAP_SHARED)
  191.     } else {
  192.         slice, err = syscall.Mmap(int(fl.Fd()), 0, int(stat.Size()), syscall.PROT_READ, syscall.MAP_PRIVATE)
  193.     }
  194.     if err != nil {
  195.         panic(err)
  196.     }
  197.     for i := 0; i < *n; i++ {
  198.         buf := tinyReader{b: slice}
  199.         limited := io.LimitReader(&buf, 20*1024*1024)
  200.         _, err := io.CopyN(sock, limited, 10*1024*1024)
  201.         if err != nil {
  202.             panic(err)
  203.         }
  204.     }
  205.     syscall.Munmap(slice)
  206.     sock.Close()
  207. }
  208.  
  209. func n2s(t int64) float64 {
  210.     return float64(t) / 1e9
  211. }
  212.  
  213. func main() {
  214.     start := time.Now()
  215.     flag.Parse()
  216.     if *gomaxprocs > 1 {
  217.         runtime.GOMAXPROCS(*gomaxprocs)
  218.     }
  219.     if *mode >= len(modeNames) {
  220.         flag.Usage()
  221.         os.Exit(1)
  222.     }
  223.     fmt.Println(modeNames[*mode])
  224.     fl, err := os.Open("test_file.txt")
  225.     if err != nil {
  226.         panic(err)
  227.     }
  228.  
  229.     addr := net.TCPAddr{IP: net.ParseIP("127.0.0.1"), Port: 8213}
  230.     listen, err := net.ListenTCP("tcp", &addr)
  231.     if err != nil {
  232.         panic(err)
  233.     }
  234.     go func() {
  235.         cl, err := net.DialTCP("tcp", nil, &addr)
  236.         if err != nil {
  237.             panic(err)
  238.         }
  239.         switch *mode {
  240.         case 0:
  241.             sendfile(cl, fl)
  242.         case 1:
  243.             mapcopy(cl, fl)
  244.         case 2:
  245.             mode2(cl, fl)
  246.         case 3:
  247.             mapcopy2(cl, fl)
  248.         }
  249.         cl.Close()
  250.         fl.Close()
  251.     }()
  252.     sock, err := listen.Accept()
  253.     if err != nil {
  254.         panic(err)
  255.     }
  256.     buf := [256 * 1024]byte{}
  257.     for err == nil {
  258.         _, err = sock.Read(buf[:])
  259.     }
  260.     if err != io.EOF {
  261.         panic(err)
  262.     }
  263.     lasts := time.Now().Sub(start)
  264.     sock.Close()
  265.     listen.Close()
  266.  
  267.     var rusage syscall.Rusage
  268.     err = syscall.Getrusage(syscall.RUSAGE_SELF, &rusage)
  269.     if err != nil {
  270.         panic(err)
  271.     }
  272.     fmt.Printf("real\t%4.3f\nuser\t%4.3f\nsys\t%4.3f\n",
  273.         n2s(int64(lasts)),
  274.         n2s(rusage.Utime.Nano()),
  275.         n2s(rusage.Stime.Nano()))
  276. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement