From 382e13d099fcf5f5994290892ab258fbebbdc5e3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Justin=20Nu=C3=9F?= Date: Fri, 12 May 2017 17:29:33 +0200 Subject: [PATCH] Avoid allocating on each call to rows.Columns (#444) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Cache column names for result sets * Test that Columns() avoids allocating on second call * Add Justin Nuß to the AUTHORS file --- AUTHORS | 1 + driver_test.go | 33 +++++++++++++++++++++++++++++++++ rows.go | 11 +++++++++-- 3 files changed, 43 insertions(+), 2 deletions(-) diff --git a/AUTHORS b/AUTHORS index a6b845f72..1928dac89 100644 --- a/AUTHORS +++ b/AUTHORS @@ -32,6 +32,7 @@ Jian Zhen Joshua Prunier Julien Lefevre Julien Schmidt +Justin Nuß Kamil Dziedzic Kevin Malachowski Lennart Rudolph diff --git a/driver_test.go b/driver_test.go index 46b8ca698..07f7e79b9 100644 --- a/driver_test.go +++ b/driver_test.go @@ -1916,3 +1916,36 @@ func TestInterruptBySignal(t *testing.T) { } }) } + +func TestColumnsReusesSlice(t *testing.T) { + rows := mysqlRows{ + rs: resultSet{ + columns: []mysqlField{ + { + tableName: "test", + name: "A", + }, + { + tableName: "test", + name: "B", + }, + }, + }, + } + + allocs := testing.AllocsPerRun(1, func() { + cols := rows.Columns() + + if len(cols) != 2 { + t.Fatalf("expected 2 columns, got %d", len(cols)) + } + }) + + if allocs != 0 { + t.Fatalf("expected 0 allocations, got %d", int(allocs)) + } + + if rows.rs.columnNames == nil { + t.Fatalf("expected columnNames to be set, got nil") + } +} diff --git a/rows.go b/rows.go index ad66a8e6e..13905e216 100644 --- a/rows.go +++ b/rows.go @@ -22,8 +22,9 @@ type mysqlField struct { } type resultSet struct { - columns []mysqlField - done bool + columns []mysqlField + columnNames []string + done bool } type mysqlRows struct { @@ -40,6 +41,10 @@ type textRows struct { } func (rows *mysqlRows) Columns() []string { + if rows.rs.columnNames != nil { + return rows.rs.columnNames + } + columns := make([]string, len(rows.rs.columns)) if rows.mc != nil && rows.mc.cfg.ColumnsWithAlias { for i := range columns { @@ -54,6 +59,8 @@ func (rows *mysqlRows) Columns() []string { columns[i] = rows.rs.columns[i].name } } + + rows.rs.columnNames = columns return columns }