ODS load perf: accelerate CompileXML for formula by stringify and compare.

For long columns of repeated formula, it is far faster to convert a formula
to a string and compare to see if the next cell in a column matches, than
it is to parse the formula string itself (sad but true).

This saves 29s of 131s of load time for my (admittedly large) ODS file.

Re-instate commit - with pCode now correctly intialized.

Change-Id: Ib25840e7916c3e1c681c8100678770b7ab7222ab
diff --git a/sc/source/core/data/formulacell.cxx b/sc/source/core/data/formulacell.cxx
index afa969d..0429a50 100644
--- a/sc/source/core/data/formulacell.cxx
+++ b/sc/source/core/data/formulacell.cxx
@@ -1184,9 +1184,50 @@ void ScFormulaCell::CompileXML( sc::CompileFormulaContext& rCxt, ScProgress& rPr
    // pCode may not deleted for queries, but must be empty
    if ( pCode )
        pCode->Clear();
    ScTokenArray* pCodeOld = pCode;
    pCode = aComp.CompileString( aFormula, aFormulaNmsp );
    delete pCodeOld;

    bool bSkipCompile = false;

    if ( !mxGroup && aFormulaNmsp.isEmpty() ) // optimization
    {
        ScAddress aPreviousCell( aPos );
        aPreviousCell.IncRow( -1 );
        ScFormulaCell *pPreviousCell = pDocument->GetFormulaCell( aPreviousCell );
        if( pPreviousCell )
        {
            // Now try to convert to a string quickly ...
            ScCompiler aBackComp( rCxt, aPos, *(pPreviousCell->pCode) );
            OUStringBuffer aShouldBeBuf;
            aBackComp.CreateStringFromTokenArray( aShouldBeBuf );

            assert( aFormula[0] == '=' );
            OUString aShouldBe = aShouldBeBuf.makeStringAndClear();
            if( aFormula.getLength() == aShouldBe.getLength() + 1 &&
                aFormula.match( aShouldBe, 1 ) ) // initial '='
            {
                // Put them in the same formula group.
                ScFormulaCellGroupRef xGroup = pPreviousCell->GetCellGroup();
                if (!xGroup) // Last cell is not grouped yet. Start a new group.
                    xGroup = pPreviousCell->CreateCellGroup(1, false);
                ++xGroup->mnLength;
                SetCellGroup( xGroup );

                bSkipCompile = true;
                pCode = pPreviousCell->pCode;

                SAL_INFO( "sc", "merged '" << aFormula << "' == "
                          "'" << aShouldBe << "'" <<
                          " extend group to " << xGroup->mnLength );
            }
        }
    }

    if (!bSkipCompile)
    {
        ScTokenArray* pCodeOld = pCode;
        pCode = aComp.CompileString( aFormula, aFormulaNmsp );
        delete pCodeOld;
    }

    if( !pCode->GetCodeError() )
    {
        if ( !pCode->GetLen() )