Eliminate allocations when using ExchangeBuffer()

This commit is contained in:
Miek Gieben 2011-08-04 13:17:36 +02:00
parent 069c5237f5
commit c170e0bbaa
2 changed files with 17 additions and 15 deletions

View File

@ -18,6 +18,7 @@ func main() {
tcp := flag.Bool("tcp", false, "TCP mode") tcp := flag.Bool("tcp", false, "TCP mode")
nsid := flag.Bool("nsid", false, "ask for NSID") nsid := flag.Bool("nsid", false, "ask for NSID")
queries := flag.Int("queries", 20, "number of concurrent queries to perform") queries := flag.Int("queries", 20, "number of concurrent queries to perform")
maxproc := flag.Int("maxproc", 4, "set GOMAXPROCS to this value")
looptime := flag.Int("time", 2, "number of seconds to query") looptime := flag.Int("time", 2, "number of seconds to query")
cpuprofile := flag.String("cpuprofile", "", "write cpu profile to file") cpuprofile := flag.String("cpuprofile", "", "write cpu profile to file")
flag.Usage = func() { flag.Usage = func() {
@ -41,7 +42,7 @@ func main() {
pprof.StartCPUProfile(f) pprof.StartCPUProfile(f)
defer pprof.StopCPUProfile() defer pprof.StopCPUProfile()
} }
runtime.GOMAXPROCS(*queries) runtime.GOMAXPROCS(*maxproc)
Flags: Flags:
for i := 0; i < flag.NArg(); i++ { for i := 0; i < flag.NArg(); i++ {
@ -94,6 +95,7 @@ Flags:
for i := 0; i < *queries; i++ { for i := 0; i < *queries; i++ {
go func() { go func() {
println("starting querier") println("starting querier")
pktbuf := make([]byte, dns.DefaultMsgSize)
c := dns.NewClient() c := dns.NewClient()
if *tcp { if *tcp {
c.Net = "tcp" c.Net = "tcp"
@ -117,9 +119,11 @@ Flags:
for { for {
// set Id // set Id
mbuf[0], mbuf[1] = byte(qid >> 8), byte(qid) mbuf[0], mbuf[1] = byte(qid >> 8), byte(qid)
c.ExchangeBuffer(mbuf, nameserver) if ok := c.ExchangeBuffer(mbuf, nameserver, pktbuf); !ok {
println("weird reply", qid)
}
queries_send++ // global var...??? queries_send++ // global var...???
qid++ // let is overflow and wrap qid++ // let it overflow and wrap
/* /*
if r == nil { if r == nil {
println("weird reply", qid) println("weird reply", qid)

View File

@ -191,26 +191,24 @@ func (c *Client) Do(m *Msg, a string) {
// ExchangeBuf performs a synchronous query. It sends the buffer m to the // ExchangeBuf performs a synchronous query. It sends the buffer m to the
// address (net.Addr?) contained in a // address (net.Addr?) contained in a
func (c *Client) ExchangeBuffer(m []byte, a string) []byte { func (c *Client) ExchangeBuffer(inbuf []byte, a string, outbuf []byte) bool {
w := new(reply) w := new(reply)
w.client = c w.client = c
w.addr = a w.addr = a
_, err := w.writeClient(m) _, err := w.writeClient(inbuf)
defer w.closeClient() // XXX here?? what about TCP which should remain open defer w.closeClient() // XXX here?? what about TCP which should remain open
if err != nil { if err != nil {
println(err.String()) println(err.String())
return nil return false
} }
// udp / tcp TODO // udp / tcp TODO
p := make([]byte, DefaultMsgSize) n, err := w.readClient(outbuf)
n, err := w.readClient(p)
if err != nil { if err != nil {
return nil return false
} }
p = p[:n] outbuf = outbuf[:n]
return p return true
} }
// Exchange performs an synchronous query. It sends the message m to the address // Exchange performs an synchronous query. It sends the message m to the address
@ -220,12 +218,12 @@ func (c *Client) Exchange(m *Msg, a string) *Msg {
if !ok { if !ok {
panic("failed to pack message") panic("failed to pack message")
} }
p := c.ExchangeBuffer(out, a) in := make([]byte, DefaultMsgSize)
if p == nil { if ok := c.ExchangeBuffer(out, a, in); !ok {
return nil return nil
} }
r := new(Msg) r := new(Msg)
if ok := r.Unpack(p); !ok { if ok := r.Unpack(in); !ok {
return nil return nil
} }
return r return r