Skip to content
This repository was archived by the owner on Aug 13, 2025. It is now read-only.

Commit 7c33d07

Browse files
authored
Merge pull request #827 from tealeg/speed-up-sharedstringreftable
Stop allocating in the loop when we load the Shared Strings Ref Table
2 parents cbf4534 + 9d67881 commit 7c33d07

File tree

6 files changed

+35
-34
lines changed

6 files changed

+35
-34
lines changed

file.go

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -202,15 +202,15 @@ func (f *File) AddSheetWithCellStore(sheetName string, constructor CellStoreCons
202202
if _, exists := f.Sheet[sheetName]; exists {
203203
return nil, fmt.Errorf("duplicate sheet name '%s'.", sheetName)
204204
}
205-
205+
206206
if err := IsSaneSheetName(sheetName); err != nil {
207207
return nil, fmt.Errorf("sheet name is not valid: %w", err)
208208
}
209209
sheet := &Sheet{
210-
Name: sheetName,
211-
File: f,
212-
Selected: len(f.Sheets) == 0,
213-
Cols: &ColStore{},
210+
Name: sheetName,
211+
File: f,
212+
Selected: len(f.Sheets) == 0,
213+
Cols: &ColStore{},
214214
cellStoreName: sheetName,
215215
}
216216

@@ -335,7 +335,7 @@ func autoFilterDefinedName(sheet *Sheet, sheetIndex int) (*xlsxDefinedName, erro
335335
// representing the file in terms of the structure of an XLSX file.
336336
func (f *File) MakeStreamParts() (map[string]string, error) {
337337
var parts map[string]string
338-
var refTable *RefTable = NewSharedStringRefTable()
338+
var refTable *RefTable = NewSharedStringRefTable(10000) // 10000 is arbitrary
339339
refTable.isWrite = true
340340
var workbookRels WorkBookRels = make(WorkBookRels)
341341
var err error
@@ -465,7 +465,7 @@ func (f *File) MakeStreamParts() (map[string]string, error) {
465465
// MarshallParts constructs a map of file name to XML content representing the file
466466
// in terms of the structure of an XLSX file.
467467
func (f *File) MarshallParts(zipWriter *zip.Writer) error {
468-
var refTable *RefTable = NewSharedStringRefTable()
468+
var refTable *RefTable = NewSharedStringRefTable(10000) // 10000 is arbitrary
469469
refTable.isWrite = true
470470
var workbookRels WorkBookRels = make(WorkBookRels)
471471
var err error

file_test.go

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -405,7 +405,6 @@ func TestFile(t *testing.T) {
405405

406406
blokes, err := OpenFile(p)
407407
c.Assert(err, qt.IsNil)
408-
409408

410409
dave := blokes.Sheets[0]
411410
if dave.currentRow != nil {

memory.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -102,9 +102,10 @@ func (mr *MemoryRow) ForEachCell(cvf CellVisitorFunc, option ...CellVisitorOptio
102102
}
103103
}
104104
cellCount := len(mr.cells)
105+
var c *Cell
105106
if !flags.skipEmptyCells {
106107
for ci := cellCount; ci < mr.row.Sheet.MaxCol; ci++ {
107-
c := mr.GetCell(ci)
108+
c = mr.GetCell(ci)
108109
err := cvf(c)
109110
if err != nil {
110111
return err

reftable.go

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -14,10 +14,11 @@ type RefTable struct {
1414
}
1515

1616
// NewSharedStringRefTable creates a new, empty RefTable.
17-
func NewSharedStringRefTable() *RefTable {
17+
func NewSharedStringRefTable(size int) *RefTable {
1818
rt := RefTable{}
19-
rt.knownStrings = make(map[string]int)
20-
rt.knownRichTexts = make(map[string][]int)
19+
rt.indexedStrings = make([]plainTextOrRichText, 0, size)
20+
rt.knownStrings = make(map[string]int, size)
21+
rt.knownRichTexts = make(map[string][]int, size)
2122
return &rt
2223
}
2324

@@ -26,7 +27,7 @@ func NewSharedStringRefTable() *RefTable {
2627
// by numeric index - this is the model used within XLSX worksheet (a
2728
// numeric reference is stored to a shared cell value).
2829
func MakeSharedStringRefTable(source *xlsxSST) *RefTable {
29-
reftable := NewSharedStringRefTable()
30+
reftable := NewSharedStringRefTable(len(source.SI))
3031
reftable.isWrite = false
3132
for _, si := range source.SI {
3233
if len(si.R) > 0 {

reftable_test.go

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ var reftabletest_sharedStringsXMLStr = (`<?xml version="1.0" encoding="UTF-8" st
5050
// We can add a new string to the RefTable
5151
func TestRefTableAddString(t *testing.T) {
5252
c := qt.New(t)
53-
refTable := NewSharedStringRefTable()
53+
refTable := NewSharedStringRefTable(1)
5454
index := refTable.AddString("Foo")
5555
c.Assert(index, qt.Equals, 0)
5656
p, r := refTable.ResolveSharedString(0)
@@ -60,7 +60,7 @@ func TestRefTableAddString(t *testing.T) {
6060

6161
func TestCreateNewSharedStringRefTable(t *testing.T) {
6262
c := qt.New(t)
63-
refTable := NewSharedStringRefTable()
63+
refTable := NewSharedStringRefTable(2)
6464
refTable.AddString("Foo")
6565
refTable.AddString("Bar")
6666
p, r := refTable.ResolveSharedString(0)
@@ -119,7 +119,7 @@ func TestResolveSharedString(t *testing.T) {
119119
// Test we can correctly create the xlsx.xlsxSST struct from a RefTable
120120
func TestMakeXLSXSST(t *testing.T) {
121121
c := qt.New(t)
122-
refTable := NewSharedStringRefTable()
122+
refTable := NewSharedStringRefTable(2)
123123
refTable.AddString("Foo")
124124
refTable.AddString("Bar")
125125
refTable.AddRichText([]RichTextRun{
@@ -154,7 +154,7 @@ func TestMakeXLSXSST(t *testing.T) {
154154

155155
func TestMarshalSST(t *testing.T) {
156156
c := qt.New(t)
157-
refTable := NewSharedStringRefTable()
157+
refTable := NewSharedStringRefTable(1)
158158
refTable.AddString("Foo")
159159
refTable.AddRichText([]RichTextRun{
160160
{
@@ -185,7 +185,7 @@ func TestMarshalSST(t *testing.T) {
185185

186186
func TestRefTableReadAddString(t *testing.T) {
187187
c := qt.New(t)
188-
refTable := NewSharedStringRefTable()
188+
refTable := NewSharedStringRefTable(2)
189189
refTable.isWrite = false
190190
index1 := refTable.AddString("Foo")
191191
index2 := refTable.AddString("Foo")
@@ -201,7 +201,7 @@ func TestRefTableReadAddString(t *testing.T) {
201201

202202
func TestRefTableWriteAddString(t *testing.T) {
203203
c := qt.New(t)
204-
refTable := NewSharedStringRefTable()
204+
refTable := NewSharedStringRefTable(2)
205205
refTable.isWrite = true
206206
index1 := refTable.AddString("Foo")
207207
index2 := refTable.AddString("Foo")
@@ -214,7 +214,7 @@ func TestRefTableWriteAddString(t *testing.T) {
214214

215215
func TestRefTableReadAddRichText(t *testing.T) {
216216
c := qt.New(t)
217-
refTable := NewSharedStringRefTable()
217+
refTable := NewSharedStringRefTable(2)
218218
refTable.isWrite = false
219219
index1 := refTable.AddRichText([]RichTextRun{
220220
{
@@ -253,7 +253,7 @@ func TestRefTableReadAddRichText(t *testing.T) {
253253

254254
func TestRefTableWriteAddRichText(t *testing.T) {
255255
c := qt.New(t)
256-
refTable := NewSharedStringRefTable()
256+
refTable := NewSharedStringRefTable(2)
257257
refTable.isWrite = true
258258
index1 := refTable.AddRichText([]RichTextRun{
259259
{

sheet_test.go

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -186,7 +186,7 @@ func TestSheet(t *testing.T) {
186186

187187
var buf bytes.Buffer
188188

189-
refTable := NewSharedStringRefTable()
189+
refTable := NewSharedStringRefTable(1)
190190
styles := newXlsxStyleSheet(nil)
191191
err := sheet.MarshalSheet(&buf, refTable, styles, nil)
192192
c.Assert(err, qt.Equals, nil)
@@ -220,7 +220,7 @@ func TestSheet(t *testing.T) {
220220
row := sheet.AddRow()
221221
cell := row.AddCell()
222222
cell.Value = "A cell!"
223-
refTable := NewSharedStringRefTable()
223+
refTable := NewSharedStringRefTable(1)
224224
styles := newXlsxStyleSheet(nil)
225225
var output bytes.Buffer
226226
err := sheet.MarshalSheet(&output, refTable, styles, nil)
@@ -256,7 +256,7 @@ func TestSheet(t *testing.T) {
256256
cell1 := row.AddCell()
257257
cell1.Value = "A cell!"
258258

259-
refTable := NewSharedStringRefTable()
259+
refTable := NewSharedStringRefTable(1)
260260
styles := newXlsxStyleSheet(nil)
261261

262262
var output bytes.Buffer
@@ -285,7 +285,7 @@ func TestSheet(t *testing.T) {
285285

286286
var buf bytes.Buffer
287287

288-
refTable := NewSharedStringRefTable()
288+
refTable := NewSharedStringRefTable(1)
289289
styles := newXlsxStyleSheet(nil)
290290
err := sheet.MarshalSheet(&buf, refTable, styles, nil)
291291
c.Assert(err, qt.Equals, nil)
@@ -303,7 +303,7 @@ func TestSheet(t *testing.T) {
303303
row := sheet.AddRow()
304304
cell := row.AddCell()
305305
cell.Value = "A cell!"
306-
refTable := NewSharedStringRefTable()
306+
refTable := NewSharedStringRefTable(1)
307307
styles := newXlsxStyleSheet(nil)
308308
var output strings.Builder
309309
err := sheet.MarshalSheet(&output, refTable, styles, nil)
@@ -325,7 +325,7 @@ func TestSheet(t *testing.T) {
325325
cell.Value = "A cell (with value 2)!"
326326
var buf bytes.Buffer
327327

328-
refTable := NewSharedStringRefTable()
328+
refTable := NewSharedStringRefTable(2)
329329
styles := newXlsxStyleSheet(nil)
330330
err := sheet.MarshalSheet(&buf, refTable, styles, nil)
331331
c.Assert(err, qt.Equals, nil)
@@ -457,7 +457,7 @@ func TestSheet(t *testing.T) {
457457

458458
var buf bytes.Buffer
459459

460-
refTable := NewSharedStringRefTable()
460+
refTable := NewSharedStringRefTable(10)
461461
styles := newXlsxStyleSheet(nil)
462462
err := sheet.MarshalSheet(&buf, refTable, styles, nil)
463463
c.Assert(err, qt.Equals, nil)
@@ -498,7 +498,7 @@ func TestMakeXLSXSheet(t *testing.T) {
498498

499499
var buf bytes.Buffer
500500

501-
refTable := NewSharedStringRefTable()
501+
refTable := NewSharedStringRefTable(4)
502502
styles := newXlsxStyleSheet(nil)
503503
err := sheet.MarshalSheet(&buf, refTable, styles, nil)
504504
c.Assert(err, qt.Equals, nil)
@@ -548,7 +548,7 @@ func TestMakeXLSXSheet(t *testing.T) {
548548
cell2.SetStyle(style2)
549549
var buf bytes.Buffer
550550

551-
refTable := NewSharedStringRefTable()
551+
refTable := NewSharedStringRefTable(2)
552552
styles := newXlsxStyleSheet(nil)
553553
err := sheet.MarshalSheet(&buf, refTable, styles, nil)
554554
c.Assert(err, qt.Equals, nil)
@@ -594,7 +594,7 @@ func TestMakeXLSXSheet(t *testing.T) {
594594
sheet.SetColWidth(1, 1, 10.5)
595595
var buf bytes.Buffer
596596

597-
refTable := NewSharedStringRefTable()
597+
refTable := NewSharedStringRefTable(1)
598598
styles := newXlsxStyleSheet(nil)
599599
err := sheet.MarshalSheet(&buf, refTable, styles, nil)
600600
c.Assert(err, qt.Equals, nil)
@@ -668,7 +668,7 @@ func TestMakeXLSXSheet(t *testing.T) {
668668
cell1.SetStyle(style1)
669669
var buf bytes.Buffer
670670

671-
refTable := NewSharedStringRefTable()
671+
refTable := NewSharedStringRefTable(1)
672672
styles := newXlsxStyleSheet(nil)
673673
err := sheet.MarshalSheet(&buf, refTable, styles, nil)
674674
c.Assert(err, qt.Equals, nil)
@@ -716,7 +716,7 @@ func TestMakeXLSXSheet(t *testing.T) {
716716

717717
// var buf bytes.Buffer
718718

719-
refTable := NewSharedStringRefTable()
719+
refTable := NewSharedStringRefTable(9)
720720
styles := newXlsxStyleSheet(nil)
721721

722722
xSheet := sheet.makeXLSXSheet(refTable, styles, nil)
@@ -796,7 +796,7 @@ func TestTemp(t *testing.T) {
796796

797797
var buf bytes.Buffer
798798

799-
refTable := NewSharedStringRefTable()
799+
refTable := NewSharedStringRefTable(1)
800800
styles := newXlsxStyleSheet(nil)
801801
err := sheet.MarshalSheet(&buf, refTable, styles, nil)
802802
c.Assert(err, qt.Equals, nil)

0 commit comments

Comments
 (0)