diff --git a/lib.go b/lib.go index 88aa3a1..7dcc09e 100644 --- a/lib.go +++ b/lib.go @@ -206,8 +206,9 @@ func CoordinatesToCellName(col, row int) (string, error) { if col < 1 || row < 1 { return "", fmt.Errorf("invalid cell coordinates [%d, %d]", col, row) } + //Using itoa will save more memory colname, err := ColumnNumberToName(col) - return fmt.Sprintf("%s%d", colname, row), err + return colname + strconv.Itoa(row), err } // boolPtr returns a pointer to a bool with the given value. diff --git a/sheet.go b/sheet.go index 8da2e89..caf87d9 100644 --- a/sheet.go +++ b/sheet.go @@ -120,18 +120,26 @@ func (f *File) workBookWriter() { // workSheetWriter provides a function to save xl/worksheets/sheet%d.xml after // serialize structure. func (f *File) workSheetWriter() { + + // optimize memory alloc + var arr []byte + buffer := bytes.NewBuffer(arr) + encoder := xml.NewEncoder(buffer) + for p, sheet := range f.Sheet { if sheet != nil { for k, v := range sheet.SheetData.Row { f.Sheet[p].SheetData.Row[k].C = trimCell(v.C) } - output, _ := xml.Marshal(sheet) - f.saveFileList(p, replaceRelationshipsBytes(f.replaceNameSpaceBytes(p, output))) + // reusing buffer + encoder.Encode(sheet) + f.saveFileList(p, replaceRelationshipsBytes(f.replaceNameSpaceBytes(p, buffer.Bytes()))) ok := f.checked[p] if ok { delete(f.Sheet, p) f.checked[p] = false } + buffer.Reset() } } } diff --git a/sheet_test.go b/sheet_test.go index 1a59b65..4626003 100644 --- a/sheet_test.go +++ b/sheet_test.go @@ -3,6 +3,7 @@ package excelize import ( "fmt" "path/filepath" + "strconv" "strings" "testing" @@ -344,3 +345,36 @@ func TestSetSheetName(t *testing.T) { f.SetSheetName("Sheet1", "Sheet1") assert.Equal(t, "Sheet1", f.GetSheetName(0)) } + +func BenchmarkNewSheet(b *testing.B) { + b.RunParallel(func(pb *testing.PB) { + for pb.Next() { + newSheetWithSet() + } + }) +} +func newSheetWithSet() { + file := NewFile() + file.NewSheet("sheet1") + for i := 0; i < 1000; i++ { + file.SetCellInt("sheet1", "A"+strconv.Itoa(i+1), i) + } + file = nil +} + +func BenchmarkFile_SaveAs(b *testing.B) { + b.RunParallel(func(pb *testing.PB) { + for pb.Next() { + newSheetWithSave() + } + + }) +} +func newSheetWithSave() { + file := NewFile() + file.NewSheet("sheet1") + for i := 0; i < 1000; i++ { + file.SetCellInt("sheet1", "A"+strconv.Itoa(i+1), i) + } + file.Save() +} diff --git a/xmlWorksheet.go b/xmlWorksheet.go index 0eaa8ee..8880909 100644 --- a/xmlWorksheet.go +++ b/xmlWorksheet.go @@ -313,20 +313,20 @@ type xlsxSheetData struct { // xlsxRow directly maps the row element. The element expresses information // about an entire row of a worksheet, and contains all cell definitions for a // particular row in the worksheet. -type xlsxRow struct { - Collapsed bool `xml:"collapsed,attr,omitempty"` +type xlsxRow struct { // alignment word + C []xlsxC `xml:"c"` + R int `xml:"r,attr,omitempty"` + Spans string `xml:"spans,attr,omitempty"` + S int `xml:"s,attr,omitempty"` CustomFormat bool `xml:"customFormat,attr,omitempty"` - CustomHeight bool `xml:"customHeight,attr,omitempty"` - Hidden bool `xml:"hidden,attr,omitempty"` Ht float64 `xml:"ht,attr,omitempty"` + Hidden bool `xml:"hidden,attr,omitempty"` + CustomHeight bool `xml:"customHeight,attr,omitempty"` OutlineLevel uint8 `xml:"outlineLevel,attr,omitempty"` - Ph bool `xml:"ph,attr,omitempty"` - R int `xml:"r,attr,omitempty"` - S int `xml:"s,attr,omitempty"` - Spans string `xml:"spans,attr,omitempty"` - ThickBot bool `xml:"thickBot,attr,omitempty"` + Collapsed bool `xml:"collapsed,attr,omitempty"` ThickTop bool `xml:"thickTop,attr,omitempty"` - C []xlsxC `xml:"c"` + ThickBot bool `xml:"thickBot,attr,omitempty"` + Ph bool `xml:"ph,attr,omitempty"` } // xlsxSortState directly maps the sortState element. This collection @@ -456,6 +456,7 @@ type DataValidation struct { // s (Shared String) | Cell containing a shared string. // str (String) | Cell containing a formula string. // +// fixme: how to make this structure smaller; cur size is 152 bytes. it's be too bigger. type xlsxC struct { XMLName xml.Name `xml:"c"` XMLSpace xml.Attr `xml:"space,attr,omitempty"`