Avoid ScTokenArray thrash

Allocate ScTokenArray object only once per worker thread, fill it
for the first row/cell and reuse them for subsequent rows/cells
if possible.

Change-Id: If8f20da618938d0e189224f189b4763815702e10
diff --git a/sc/source/core/tool/formulagroup.cxx b/sc/source/core/tool/formulagroup.cxx
index f0183c6..b7968ac 100644
--- a/sc/source/core/tool/formulagroup.cxx
+++ b/sc/source/core/tool/formulagroup.cxx
@@ -171,12 +171,14 @@ public:
    {
        double fNan;
        rtl::math::setNan(&fNan);
        ScTokenArray aCode2;
        for (SCROW i = mnIdx; i <= mnLastIdx; ++i, maBatchTopPos.IncRow())
        {
            ScTokenArray aCode2;
            formula::FormulaTokenArrayPlainIterator aIter(mrCode);
            for (const formula::FormulaToken* p = aIter.First(); p; p = aIter.Next())
            size_t nTokIdx = 0;
            for (const formula::FormulaToken* p = aIter.First(); p; p = aIter.Next(), ++nTokIdx)
            {
                formula::FormulaToken* pTargetTok = aCode2.TokenAt(nTokIdx);
                switch (p->GetType())
                {
                    case formula::svSingleVectorRef:
@@ -200,14 +202,25 @@ public:
                        {
                            // This is a string cell.
                            svl::SharedStringPool& rPool = mrDoc.GetSharedStringPool();
                            aCode2.AddString(rPool.intern(OUString(pStr)));
                            if ( !pTargetTok )
                                aCode2.AddString(rPool.intern(OUString(pStr)));
                            else
                                pTargetTok->SetString(rPool.intern(OUString(pStr)));
                        }
                        else if (rtl::math::isNan(fVal))
                        {
                            // Value of NaN represents an empty cell.
                            aCode2.AddToken(ScEmptyCellToken(false, false));
                            if ( !pTargetTok )
                                aCode2.AddToken(ScEmptyCellToken(false, false));
                        }
                        else
                        {
                            // Numeric cell.
                            aCode2.AddDouble(fVal);
                            if ( !pTargetTok )
                                aCode2.AddDouble(fVal);
                            else
                                pTargetTok->GetDoubleAsReference() = fVal;
                        }
                    }
                    break;
                    case formula::svDoubleVectorRef:
@@ -229,17 +242,29 @@ public:
                            aRefRange.aEnd.SetRow(mrTopPos.Row() + nRowEnd);
                            aRef.InitRange(aRefRange);
                            formula::FormulaTokenRef xTok(new ScMatrixRangeToken(pMat, aRef));
                            aCode2.AddToken(*xTok);
                            if ( !pTargetTok )
                                aCode2.AddToken(*xTok);
                            else
                                aCode2.ReplaceToken(nTokIdx, xTok.get(), formula::FormulaTokenArray::CODE_ONLY);
                        }
                        else
                        {
                            ScMatrixToken aTok(pMat);
                            aCode2.AddToken(aTok);
                            if ( !pTargetTok )
                            {
                                ScMatrixToken aTok(pMat);
                                aCode2.AddToken(aTok);
                            }
                            else
                            {
                                ScMatrixToken* pMatTok = new ScMatrixToken(pMat);
                                aCode2.ReplaceToken(nTokIdx, pMatTok, formula::FormulaTokenArray::CODE_ONLY);
                            }
                        }
                    }
                    break;
                    default:
                        aCode2.AddToken(*p);
                        if ( !pTargetTok )
                            aCode2.AddToken(*p);
                } // end of switch statement
            } // end of formula token for loop