optimize memory allocation (#722)
* optimize marshal * optimize mem alloc * add benchmark testing * add NewSheetWithRowNum testing * sync struct fields order * add BenchmarkNewSheetWithStreamWriter * delete NewSheetWithRowNum and benchmark test
This commit is contained in:
parent
9d470bb38f
commit
fcca8a3838
3
lib.go
3
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.
|
||||
|
|
12
sheet.go
12
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()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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()
|
||||
}
|
||||
|
|
|
@ -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"`
|
||||
CustomFormat bool `xml:"customFormat,attr,omitempty"`
|
||||
CustomHeight bool `xml:"customHeight,attr,omitempty"`
|
||||
Hidden bool `xml:"hidden,attr,omitempty"`
|
||||
Ht float64 `xml:"ht,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"`
|
||||
ThickTop bool `xml:"thickTop,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"`
|
||||
Ht float64 `xml:"ht,attr,omitempty"`
|
||||
Hidden bool `xml:"hidden,attr,omitempty"`
|
||||
CustomHeight bool `xml:"customHeight,attr,omitempty"`
|
||||
OutlineLevel uint8 `xml:"outlineLevel,attr,omitempty"`
|
||||
Collapsed bool `xml:"collapsed,attr,omitempty"`
|
||||
ThickTop bool `xml:"thickTop,attr,omitempty"`
|
||||
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"`
|
||||
|
|
Loading…
Reference in New Issue