From c9d5ff919c87566fdbc6a2ddde0bcd30d471c425 Mon Sep 17 00:00:00 2001 From: Ashod Nakashian Date: Sun, 19 Jun 2016 12:13:35 -0400 Subject: bccu#1893 - [PERFORMANCE] .uno:ViewRowColumnHeaders too slow For very large spreadsheets, the boost json generator (property_tree) is extremely slow and memory-inefficient. There is little need for generic json generator, however, since there are exactly two nodes (rows and columns) and each is an array of size/text pairs. The new logic uses a string with reserved capacity to accomodate the output and generates it in one step. The speed improvement is orders of magnitude (hours to seconds) for very large spreadsheets. Change-Id: Ifaf316c270ed6e4b923ec44189a315f69e7e9b0e Reviewed-on: https://gerrit.libreoffice.org/26480 Reviewed-by: Ashod Nakashian Tested-by: Ashod Nakashian --- sc/source/ui/view/tabview.cxx | 45 +++++++++++++++++++++---------------------- 1 file changed, 22 insertions(+), 23 deletions(-) diff --git a/sc/source/ui/view/tabview.cxx b/sc/source/ui/view/tabview.cxx index c7cf4cbbba02..1a6810733a30 100644 --- a/sc/source/ui/view/tabview.cxx +++ b/sc/source/ui/view/tabview.cxx @@ -2319,15 +2319,20 @@ OUString ScTabView::getRowColumnHeaders(const Rectangle& rRectangle) SCROW nEndRow = 0; pDoc->GetTiledRenderingArea(aViewData.GetTabNo(), nEndCol, nEndRow); - boost::property_tree::ptree aRows; + std::string os; + os.reserve(256 + (50 * nEndRow) + (50 * nEndCol)); + + os.append("{ \"commandName\": \".uno:ViewRowColumnHeaders\",\n"); + os.append("\"rows\": [\n"); + long nTotal = 0; long nTotalPixels = 0; for (SCROW nRow = 0; nRow <= nEndRow; ++nRow) { // nSize will be 0 for hidden rows. - sal_uInt16 nSize = pDoc->GetRowHeight(nRow, aViewData.GetTabNo()); - long nSizePixels = ScViewData::ToPixel(nSize, aViewData.GetPPTY()); - OUString aText = pRowBar[SC_SPLIT_BOTTOM]->GetEntryText(nRow); + const sal_uInt16 nSize = pDoc->GetRowHeight(nRow, aViewData.GetTabNo()); + const long nSizePixels = ScViewData::ToPixel(nSize, aViewData.GetPPTY()); + const OUString aText = pRowBar[SC_SPLIT_BOTTOM]->GetEntryText(nRow); bool bSkip = false; if (!rRectangle.IsEmpty()) @@ -2340,23 +2345,23 @@ OUString ScTabView::getRowColumnHeaders(const Rectangle& rRectangle) } if (!bSkip) { - boost::property_tree::ptree aRow; - aRow.put("size", OString::number((nTotalPixels + nSizePixels) / aViewData.GetPPTY()).getStr()); - aRow.put("text", aText.toUtf8().getStr()); - aRows.push_back(std::make_pair("", aRow)); + os.append("{ \"text\": \"").append(aText.toUtf8().getStr()).append("\", "); + os.append("\"size\": \"").append(OString::number((nTotalPixels + nSizePixels) / aViewData.GetPPTY()).getStr()).append("\" }, "); } nTotal += nSize; nTotalPixels += nSizePixels; } - boost::property_tree::ptree aCols; + os.erase(os.size() - 2); + os.append("],\n\"columns\":\n["); + nTotal = 0; nTotalPixels = 0; for (SCCOL nCol = 0; nCol <= nEndCol; ++nCol) { - sal_uInt16 nSize = pDoc->GetColWidth(nCol, aViewData.GetTabNo()); - long nSizePixels = ScViewData::ToPixel(nSize, aViewData.GetPPTX()); - OUString aText = pColBar[SC_SPLIT_LEFT]->GetEntryText(nCol); + const sal_uInt16 nSize = pDoc->GetColWidth(nCol, aViewData.GetTabNo()); + const long nSizePixels = ScViewData::ToPixel(nSize, aViewData.GetPPTX()); + const OUString aText = pColBar[SC_SPLIT_LEFT]->GetEntryText(nCol); bool bSkip = false; if (!rRectangle.IsEmpty()) @@ -2369,22 +2374,16 @@ OUString ScTabView::getRowColumnHeaders(const Rectangle& rRectangle) } if (!bSkip) { - boost::property_tree::ptree aCol; - aCol.put("size", OString::number((nTotalPixels + nSizePixels) / aViewData.GetPPTX()).getStr()); - aCol.put("text", aText.toUtf8().getStr()); - aCols.push_back(std::make_pair("", aCol)); + os.append("{ \"text\": \"").append(aText.toUtf8().getStr()).append("\", "); + os.append("\"size\": \"").append(OString::number((nTotalPixels + nSizePixels) / aViewData.GetPPTX()).getStr()).append("\" }, "); } nTotal += nSize; nTotalPixels += nSizePixels; } - boost::property_tree::ptree aTree; - aTree.put("commandName", ".uno:ViewRowColumnHeaders"); - aTree.add_child("rows", aRows); - aTree.add_child("columns", aCols); - std::stringstream aStream; - boost::property_tree::write_json(aStream, aTree); - return OUString::fromUtf8(aStream.str().c_str()); + os.erase(os.size() - 2); + os.append("]\n}"); + return OUString::fromUtf8(os.c_str()); } /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ -- cgit