Skip to content

Memory allocation optimizations #71

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 12 commits into from
63 changes: 62 additions & 1 deletion buffer.go
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,6 @@ func (b *buffer) fill(need int) (err error) {
}
return // err
}
return
}

// returns next N bytes from buffer.
Expand All @@ -72,3 +71,65 @@ func (b *buffer) readNext(need int) (p []byte, err error) {
b.length -= need
return
}

// various allocation pools

var bytesPool = make(chan []byte, 16)

// may return unzeroed bytes
func getBytes(n int) []byte {
select {
case s := <-bytesPool:
if cap(s) >= n {
return s[:n]
}
default:
}
return make([]byte, n)
}

func putBytes(s []byte) {
select {
case bytesPool <- s:
default:
}
}

var fieldPool = make(chan []mysqlField, 16)

func getMysqlFields(n int) []mysqlField {
select {
case f := <-fieldPool:
if cap(f) >= n {
return f[:n]
}
default:
}
return make([]mysqlField, n)
}

func putMysqlFields(f []mysqlField) {
select {
case fieldPool <- f:
default:
}
}

var rowsPool = make(chan *mysqlRows, 16)

func getMysqlRows() *mysqlRows {
select {
case r := <-rowsPool:
return r
default:
}
return new(mysqlRows)
}

func putMysqlRows(r *mysqlRows) {
*r = mysqlRows{} // zero it
select {
case rowsPool <- r:
default:
}
}
8 changes: 5 additions & 3 deletions connection.go
Original file line number Diff line number Diff line change
Expand Up @@ -190,13 +190,14 @@ func (mc *mysqlConn) Query(query string, args []driver.Value) (driver.Rows, erro
var resLen int
resLen, err = mc.readResultSetHeaderPacket()
if err == nil {
rows := &mysqlRows{mc, false, nil, false}
rows := getMysqlRows()
rows.mc = mc

if resLen > 0 {
// Columns
rows.columns, err = mc.readColumns(resLen)
}
return rows, err
return &mysqlRowsI{rows}, err
}
}

Expand All @@ -217,7 +218,8 @@ func (mc *mysqlConn) getSystemVar(name string) (val []byte, err error) {
var resLen int
resLen, err = mc.readResultSetHeaderPacket()
if err == nil {
rows := &mysqlRows{mc, false, nil, false}
rows := getMysqlRows()
rows.mc = mc

if resLen > 0 {
// Columns
Expand Down
1 change: 1 addition & 0 deletions errors.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ var (
errPktSync = errors.New("Commands out of sync. You can't run this command now")
errPktSyncMul = errors.New("Commands out of sync. Did you run multiple statements at once?")
errPktTooLarge = errors.New("Packet for query is too large. You can change this value on the server by adjusting the 'max_allowed_packet' variable.")
errInvConn = errors.New("Invalid Connection")
)

// error type which represents a single MySQL error
Expand Down
Loading