Kaydet (Commit) 3464bb16 authored tarafından Ashod Nakashian's avatar Ashod Nakashian Kaydeden (comit) Ashod Nakashian

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.

Reviewed-on: https://gerrit.libreoffice.org/26480Reviewed-by: 's avatarAshod Nakashian <ashnakash@gmail.com>
Tested-by: 's avatarAshod Nakashian <ashnakash@gmail.com>
(cherry picked from commit c9d5ff91)

Change-Id: Ifaf316c270ed6e4b923ec44189a315f69e7e9b0e
Reviewed-on: https://gerrit.libreoffice.org/26485Tested-by: 's avatarJenkins <ci@libreoffice.org>
Reviewed-by: 's avatarAshod Nakashian <ashnakash@gmail.com>
üst c8a94cae
...@@ -2313,15 +2313,20 @@ OUString ScTabView::getRowColumnHeaders(const Rectangle& rRectangle) ...@@ -2313,15 +2313,20 @@ OUString ScTabView::getRowColumnHeaders(const Rectangle& rRectangle)
SCROW nEndRow = 0; SCROW nEndRow = 0;
pDoc->GetTiledRenderingArea(aViewData.GetTabNo(), nEndCol, nEndRow); pDoc->GetTiledRenderingArea(aViewData.GetTabNo(), nEndCol, nEndRow);
boost::property_tree::ptree aRows; rtl::OUStringBuffer aBuffer(256 + (50 * nEndRow) + (50 * nEndCol));
aBuffer.append("{ \"commandName\": \".uno:ViewRowColumnHeaders\",\n");
aBuffer.append("\"rows\": [\n");
long nTotal = 0; long nTotal = 0;
long nTotalPixels = 0; long nTotalPixels = 0;
bool bFirstRow = true;
for (SCROW nRow = 0; nRow <= nEndRow; ++nRow) for (SCROW nRow = 0; nRow <= nEndRow; ++nRow)
{ {
// nSize will be 0 for hidden rows. // nSize will be 0 for hidden rows.
sal_uInt16 nSize = pDoc->GetRowHeight(nRow, aViewData.GetTabNo()); const sal_uInt16 nSize = pDoc->GetRowHeight(nRow, aViewData.GetTabNo());
long nSizePixels = ScViewData::ToPixel(nSize, aViewData.GetPPTY()); const long nSizePixels = ScViewData::ToPixel(nSize, aViewData.GetPPTY());
OUString aText = pRowBar[SC_SPLIT_BOTTOM]->GetEntryText(nRow); const OUString aText = pRowBar[SC_SPLIT_BOTTOM]->GetEntryText(nRow);
bool bSkip = false; bool bSkip = false;
if (!rRectangle.IsEmpty()) if (!rRectangle.IsEmpty())
...@@ -2334,23 +2339,27 @@ OUString ScTabView::getRowColumnHeaders(const Rectangle& rRectangle) ...@@ -2334,23 +2339,27 @@ OUString ScTabView::getRowColumnHeaders(const Rectangle& rRectangle)
} }
if (!bSkip) if (!bSkip)
{ {
boost::property_tree::ptree aRow; if (!bFirstRow)
aRow.put("size", OString::number((nTotalPixels + nSizePixels) / aViewData.GetPPTY()).getStr()); aBuffer.append(", ");
aRow.put("text", aText.toUtf8().getStr());
aRows.push_back(std::make_pair("", aRow)); aBuffer.append("{ \"text\": \"").append(aText).append("\", ");
aBuffer.append("\"size\": \"").append(OUString::number((nTotalPixels + nSizePixels) / aViewData.GetPPTY())).append("\" }");
bFirstRow = false;
} }
nTotal += nSize; nTotal += nSize;
nTotalPixels += nSizePixels; nTotalPixels += nSizePixels;
} }
boost::property_tree::ptree aCols; aBuffer.append("],\n\"columns\":\n[");
nTotal = 0; nTotal = 0;
nTotalPixels = 0; nTotalPixels = 0;
bFirstRow = true;
for (SCCOL nCol = 0; nCol <= nEndCol; ++nCol) for (SCCOL nCol = 0; nCol <= nEndCol; ++nCol)
{ {
sal_uInt16 nSize = pDoc->GetColWidth(nCol, aViewData.GetTabNo()); const sal_uInt16 nSize = pDoc->GetColWidth(nCol, aViewData.GetTabNo());
long nSizePixels = ScViewData::ToPixel(nSize, aViewData.GetPPTX()); const long nSizePixels = ScViewData::ToPixel(nSize, aViewData.GetPPTX());
OUString aText = pColBar[SC_SPLIT_LEFT]->GetEntryText(nCol); const OUString aText = pColBar[SC_SPLIT_LEFT]->GetEntryText(nCol);
bool bSkip = false; bool bSkip = false;
if (!rRectangle.IsEmpty()) if (!rRectangle.IsEmpty())
...@@ -2363,22 +2372,19 @@ OUString ScTabView::getRowColumnHeaders(const Rectangle& rRectangle) ...@@ -2363,22 +2372,19 @@ OUString ScTabView::getRowColumnHeaders(const Rectangle& rRectangle)
} }
if (!bSkip) if (!bSkip)
{ {
boost::property_tree::ptree aCol; if (!bFirstRow)
aCol.put("size", OString::number((nTotalPixels + nSizePixels) / aViewData.GetPPTX()).getStr()); aBuffer.append(", ");
aCol.put("text", aText.toUtf8().getStr());
aCols.push_back(std::make_pair("", aCol)); aBuffer.append("{ \"text\": \"").append(aText).append("\", ");
aBuffer.append("\"size\": \"").append(OUString::number((nTotalPixels + nSizePixels) / aViewData.GetPPTX())).append("\" }");
bFirstRow = false;
} }
nTotal += nSize; nTotal += nSize;
nTotalPixels += nSizePixels; nTotalPixels += nSizePixels;
} }
boost::property_tree::ptree aTree; aBuffer.append("]\n}");
aTree.put("commandName", ".uno:ViewRowColumnHeaders"); return aBuffer.makeStringAndClear();
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());
} }
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment