Improve performance of large Excel documents wrt cell style import.

This change improves import performance of Excel documents based on
the following changes.

1) Pool styles only once per call.

This removes SfxItemPoolCache instantiation and destruction which
is quite expensive.  This alone cuts import almost by half with
large documents with lots of styles applied.

2) Skip removal of direct formats when setting style.

The old code was iterating through all attribute regions in order
to try to remove overlapping format attributes when applying a
style.  But that's strictly not necessary (and bad for performance)
during import.  This also removes the need to re-apply the direct
formats right afterward.

3) Avoid creating a duplicate ScPatternAttr instance per XF.

There is simply no need to create a clone of the style only to put
it into the styles pool and get discarded.  This saves additional
few seconds.
This commit is contained in:
Kohei Yoshida 2011-09-06 20:52:37 -04:00
parent 2207f9c75a
commit cc2b19b992
3 changed files with 16 additions and 28 deletions

View file

@ -121,7 +121,7 @@ public:
ScPatternAttr* PutInPool( ScDocument* pDestDoc, ScDocument* pSrcDoc ) const;
void SetStyleSheet(ScStyleSheet* pNewStyle);
void SetStyleSheet(ScStyleSheet* pNewStyle, bool bClearDirectFormat = true);
const ScStyleSheet* GetStyleSheet() const { return pStyle; }
const String* GetStyleName() const;
void UpdateStyleSheet();

View file

@ -1165,17 +1165,20 @@ const String* ScPatternAttr::GetStyleName() const
}
void ScPatternAttr::SetStyleSheet( ScStyleSheet* pNewStyle )
void ScPatternAttr::SetStyleSheet( ScStyleSheet* pNewStyle, bool bClearDirectFormat )
{
if (pNewStyle)
{
SfxItemSet& rPatternSet = GetItemSet();
const SfxItemSet& rStyleSet = pNewStyle->GetItemSet();
for (sal_uInt16 i=ATTR_PATTERN_START; i<=ATTR_PATTERN_END; i++)
if (bClearDirectFormat)
{
if (rStyleSet.GetItemState(i, sal_True) == SFX_ITEM_SET)
rPatternSet.ClearItem(i);
for (sal_uInt16 i=ATTR_PATTERN_START; i<=ATTR_PATTERN_END; i++)
{
if (rStyleSet.GetItemState(i, sal_True) == SFX_ITEM_SET)
rPatternSet.ClearItem(i);
}
}
rPatternSet.SetParent(&pNewStyle->GetItemSet());
pStyle = pNewStyle;

View file

@ -1291,42 +1291,27 @@ void XclImpXF::ApplyPatternToAttrList(
list<ScAttrEntry>& rAttrs, SCROW nRow1, SCROW nRow2, sal_uInt32 nForceScNumFmt)
{
// force creation of cell style and hard formatting, do it here to have mpStyleSheet
const ScPatternAttr& rOrigPat = CreatePattern();
ScPatternAttr aNewPat = rOrigPat;
const ScPatternAttr* pPat = NULL;
CreatePattern();
ScPatternAttr& rPat = *mpPattern;
// insert into document
ScDocument& rDoc = GetDoc();
if (IsCellXF() && mpStyleSheet)
{
// Style sheet exists. Create a copy of the original pattern.
aNewPat.SetStyleSheet(mpStyleSheet);
pPat = &aNewPat;
}
if (HasUsedFlags())
{
if (!pPat)
pPat = &aNewPat;
SfxItemPoolCache aCache(rDoc.GetPool(), &rOrigPat.GetItemSet());
pPat = static_cast<const ScPatternAttr*>(&aCache.ApplyTo(*pPat, true));
// Apply style sheet. Don't clear the direct formats.
rPat.SetStyleSheet(mpStyleSheet, false);
}
if (nForceScNumFmt != NUMBERFORMAT_ENTRY_NOT_FOUND)
{
if (!pPat)
pPat = &aNewPat;
ScPatternAttr aNumPat(GetDoc().GetPool());
ScPatternAttr aNumPat(rDoc.GetPool());
GetNumFmtBuffer().FillScFmtToItemSet(aNumPat.GetItemSet(), nForceScNumFmt);
SfxItemPoolCache aCache(rDoc.GetPool(), &aNumPat.GetItemSet());
pPat = static_cast<const ScPatternAttr*>(&aCache.ApplyTo(*pPat, true));
rPat.GetItemSet().Put(aNumPat.GetItemSet());
}
// Make sure we skip unnamed styles.
if (pPat && pPat->GetStyleName())
if (rPat.GetStyleName())
{
// Check for a gap between the last entry and this one.
bool bHasGap = false;
@ -1348,7 +1333,7 @@ void XclImpXF::ApplyPatternToAttrList(
ScAttrEntry aEntry;
aEntry.nRow = nRow2;
aEntry.pPattern = static_cast<const ScPatternAttr*>(&rDoc.GetPool()->Put(*pPat));
aEntry.pPattern = static_cast<const ScPatternAttr*>(&rDoc.GetPool()->Put(rPat));
rAttrs.push_back(aEntry);
}
}