Parcourir la source

Avoid allocating on each call to rows.Columns (#444)

* Cache column names for result sets

* Test that Columns() avoids allocating on second call

* Add Justin Nuß to the AUTHORS file
Justin Nuß il y a 8 ans
Parent
commit
382e13d099
3 fichiers modifiés avec 43 ajouts et 2 suppressions
  1. 1 0
      AUTHORS
  2. 33 0
      driver_test.go
  3. 9 2
      rows.go

+ 1 - 0
AUTHORS

@@ -32,6 +32,7 @@ Jian Zhen <zhenjl at gmail.com>
 Joshua Prunier <joshua.prunier at gmail.com>
 Julien Lefevre <julien.lefevr at gmail.com>
 Julien Schmidt <go-sql-driver at julienschmidt.com>
+Justin Nuß <nuss.justin at gmail.com>
 Kamil Dziedzic <kamil at klecza.pl>
 Kevin Malachowski <kevin at chowski.com>
 Lennart Rudolph <lrudolph at hmc.edu>

+ 33 - 0
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")
+	}
+}

+ 9 - 2
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
 }