Mercurial > gemma
changeset 5364:1adbd6a5f849 extented-report
XLSX templater: Cache cell formulas for performance.
author | Sascha L. Teichmann <sascha.teichmann@intevation.de> |
---|---|
date | Wed, 23 Jun 2021 01:01:11 +0200 |
parents | 04b3fb35910c |
children | 74bae79de83e |
files | pkg/xlsx/templater.go |
diffstat | 1 files changed, 47 insertions(+), 9 deletions(-) [+] |
line wrap: on
line diff
--- a/pkg/xlsx/templater.go Tue Jun 22 21:58:28 2021 +0200 +++ b/pkg/xlsx/templater.go Wed Jun 23 01:01:11 2021 +0200 @@ -48,6 +48,16 @@ index int } +type sheetAxis struct { + sheet string + axis string +} + +type cellValue struct { + value string + err error +} + type executor struct { ctx context.Context tx *sql.Tx @@ -57,6 +67,8 @@ sourceSheet string destinationSheet string frames []frame + // Fetching formulas out of cells is very expensive so we cache them. + formulaCache map[sheetAxis]cellValue } type area struct { @@ -110,12 +122,18 @@ template *excelize.File, ) error { + //if f, err := os.Create("cpu.prof"); err == nil { + // pprof.StartCPUProfile(f) + // defer pprof.StopCPUProfile() + //} + e := executor{ - ctx: ctx, - tx: tx, - template: template, - keep: map[string]bool{}, - expressions: map[string]gval.Evaluable{}, + ctx: ctx, + tx: tx, + template: template, + keep: map[string]bool{}, + expressions: map[string]gval.Evaluable{}, + formulaCache: map[sheetAxis]cellValue{}, } oldSheets := template.GetSheetList() @@ -132,6 +150,26 @@ return nil } +var reused int + +func (e *executor) getCellFormula(sheet, axis string) (string, error) { + var ( + k = sheetAxis{sheet: sheet, axis: axis} + v cellValue + ok bool + ) + if v, ok = e.formulaCache[k]; !ok { + v.value, v.err = e.template.GetCellFormula(sheet, axis) + e.formulaCache[k] = v + } + return v.value, v.err +} + +func (e *executor) setCellFormula(sheet, axis, formula string) { + e.formulaCache[sheetAxis{sheet: sheet, axis: axis}] = cellValue{value: formula} + e.template.SetCellFormula(sheet, axis, formula) +} + func (e *executor) dispatch(action *Action) error { if len(action.Vars) > 0 { e.pushVars(action.Vars) @@ -291,8 +329,8 @@ if s, err := e.template.GetCellStyle(e.sourceSheet, src); err == nil { e.template.SetCellStyle(e.destinationSheet, dst, dst, s) } - if s, err := e.template.GetCellFormula(e.sourceSheet, src); err == nil { - e.template.SetCellFormula(e.destinationSheet, dst, s) + if s, err := e.getCellFormula(e.sourceSheet, src); err == nil { + e.setCellFormula(e.destinationSheet, dst, s) } } } @@ -358,8 +396,8 @@ if s, err := e.template.GetCellStyle(e.sourceSheet, src); err == nil { e.template.SetCellStyle(e.destinationSheet, dst, dst, s) } - if s, err := e.template.GetCellFormula(e.sourceSheet, src); err == nil { - e.template.SetCellFormula(e.destinationSheet, dst, s) + if s, err := e.getCellFormula(e.sourceSheet, src); err == nil { + e.setCellFormula(e.destinationSheet, dst, s) } if s, err := e.template.GetCellValue(e.sourceSheet, src); err == nil { if v, err := e.typedExpand(s, vars); err == nil {