github.com/gdamore/mangos@v1.4.0/perf/throughput.go (about) 1 // Copyright 2018 The Mangos Authors 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use file except in compliance with the License. 5 // You may obtain a copy of the license at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 // Package perf provides utilities to measure mangos peformance against 16 // libnanomsg' perf tools. 17 18 package main 19 20 import ( 21 "fmt" 22 "log" 23 "time" 24 25 "nanomsg.org/go-mangos" 26 "nanomsg.org/go-mangos/protocol/pair" 27 "nanomsg.org/go-mangos/transport/all" 28 ) 29 30 // ThroughputServer is the server side -- very much equivalent to local_thr in 31 // nanomsg/perf. It does the measurement by counting packets received. 32 func ThroughputServer(addr string, msgSize int, count int) { 33 s, err := pair.NewSocket() 34 if err != nil { 35 log.Fatalf("Failed to make new pair socket: %v", err) 36 } 37 defer s.Close() 38 39 all.AddTransports(s) 40 l, err := s.NewListener(addr, nil) 41 if err != nil { 42 log.Fatalf("Failed to make new listener: %v", err) 43 } 44 45 // Disable TCP no delay, please! - only valid for TCP 46 l.SetOption(mangos.OptionNoDelay, false) 47 48 // Make sure we linger a bit on close... 49 err = s.SetOption(mangos.OptionLinger, time.Second) 50 if err != nil { 51 log.Fatalf("Failed set Linger: %v", err) 52 } 53 54 err = l.Listen() 55 if err != nil { 56 log.Fatalf("Failed to listen: %v", err) 57 } 58 59 msg, err := s.RecvMsg() 60 if err != nil { 61 log.Fatalf("Failed to receive start message: %v", err) 62 } 63 msg.Free() 64 65 start := time.Now() 66 67 for i := 0; i != count; i++ { 68 msg, err := s.RecvMsg() 69 if err != nil { 70 log.Fatalf("Failed to recv: %v", err) 71 } 72 if len(msg.Body) != msgSize { 73 log.Fatalf("Received wrong message size: %d != %d", len(msg.Body), msgSize) 74 } 75 // return to cache to avoid GC 76 msg.Free() 77 } 78 79 finish := time.Now() 80 81 delta := finish.Sub(start) 82 deltasec := float64(delta) / float64(time.Second) 83 msgpersec := float64(count) / deltasec 84 mbps := (float64((count)*8*msgSize) / deltasec) / 1000000.0 85 fmt.Printf("message size: %d [B]\n", msgSize) 86 fmt.Printf("message count: %d\n", count) 87 fmt.Printf("throughput: %d [msg/s]\n", uint64(msgpersec)) 88 fmt.Printf("throughput: %.3f [Mb/s]\n", mbps) 89 } 90 91 // ThroughputClient is the client side of the latency test. It simply sends 92 // the requested number of packets of given size to the server. It corresponds 93 // to remote_thr. 94 func ThroughputClient(addr string, msgSize int, count int) { 95 s, err := pair.NewSocket() 96 if err != nil { 97 log.Fatalf("Failed to make new pair socket: %v", err) 98 } 99 defer s.Close() 100 101 all.AddTransports(s) 102 d, err := s.NewDialer(addr, nil) 103 if err != nil { 104 log.Fatalf("Failed to make new dialer: %v", err) 105 } 106 107 // Disable TCP no delay, please! 108 d.SetOption(mangos.OptionNoDelay, false) 109 110 // Make sure we linger a bit on close... 111 err = s.SetOption(mangos.OptionLinger, time.Second) 112 if err != nil { 113 log.Fatalf("Failed set Linger: %v", err) 114 } 115 116 err = d.Dial() 117 if err != nil { 118 log.Fatalf("Failed to dial: %v", err) 119 } 120 121 // 100 milliseconds to give TCP a chance to establish 122 time.Sleep(time.Millisecond * 100) 123 124 body := make([]byte, msgSize) 125 for i := 0; i < msgSize; i++ { 126 body[i] = 111 127 } 128 129 // send the start message 130 s.Send([]byte{}) 131 132 for i := 0; i < count; i++ { 133 if err = s.Send(body); err != nil { 134 log.Fatalf("Failed SendMsg: %v", err) 135 } 136 } 137 }