Spire.Doc is a professional Word .NET library specifically designed for developers to create, read, write, convert and print Word document files from any .NET platform (C#, VB.NET, ASP.NET, .NET Core) and Java applications (J2SE and J2EE) with fast and high quality performance.

Sat Apr 17, 2021 2:42 pm

Hello there and thanks Spire team for all your efforts.
I have a problem with saving large word files;
when the word file is around 1000 pages or below, it took less than 1 minute to save it to a file,
but when the page number increase to around 2000, suddenly the time it needs to save increases dramatically.
you expect the time to be doubled but guess what, it takes around 4-5 minutes to save a file with 2000 pages!

Need to mention that in my project speed of saving files is vital;
I tried several thoughts like changing file format, decreasing paragraph styles, or even saving 2 separate files and at the end merging them together,
but non of them solved my problem.
How can I increase saving speed of word file ?
The programming language is C#.

Any help would be appreciated.

Leviamatte
 
Posts: 6
Joined: Sat Apr 17, 2021 2:20 pm

Mon Apr 19, 2021 3:00 am

Hello,

Thanks for your inquiry!

I simulated a simple comparison test with the latest Spire.Doc V9.4.1 to save 1000 pages of document and 2000 pages of document. It took 2.225s for 1000 pages and 4.268s for 2000 pages, which is the normal document save time. If you were not using the latest version, I recommend that you have a try first.

If so, and the speed of saving the file has not improved. Since the speed of saving the file depends on the content in it, to help us reproduce and investigate your issue quickly and efficiently, please provide us with your input file (if any), testing code, target framework(e.g. .Net Framework 4.6.1), system information (E.g. Win7, 64 bit) and region setting (E.g. China, Chinese) for reference. You can also send them to us via email (support@e-iceblue.com) to protect your privacy.

Thanks in advance.

Sincerely,
Marcia
E-iceblue support team
User avatar

Marcia.Zhou
 
Posts: 408
Joined: Wed Nov 04, 2020 2:29 am

Mon Apr 19, 2021 10:31 am

Hello there and thank you for your reply,

I was using version 8.3.15 of Spire.Doc.
After reading your reply, I downloaded latest version of Spire.Doc (Hot fix 9.4.1) and replaced it with the old one, and the problem was still there.

The target framework is 4, and programming language is C#
My PC configuration is:
OS: Win 10 x64 build number of 19041.928
CPU: Intel core-i7 7700k
Memory: 8 GB of DDR4 3200mh
and also need to mention that I'm saving the file on a Solid State Drive (which is faster than HDD).

The function I'm using to generate doc file is below:
Code: Select all
private Document getEncodeFile()
        {
            if (txtLayerTo.Text == string.Empty)
            {
                txtLayerTo.Invoke((MethodInvoker)delegate
                {
                    txtLayerTo.Text = ourMap.Height.ToString();
                });
            }
            if (txtLayerFrom.Text == string.Empty)
            {
                txtLayerFrom.Invoke((MethodInvoker)delegate
                {
                    txtLayerFrom.Text = "1";
                });
            }
            string newLine = Environment.NewLine;
            Document docNodes = new Document();
            Section sec = docNodes.AddSection();
            sec.PageSetup.PageSize = PageSize.A4;
            sec.PageSetup.Orientation = PageOrientation.Portrait;
            sec.PageSetup.Margins.Top = 36;
            sec.PageSetup.Margins.Right = 36;
            sec.PageSetup.Margins.Bottom = 36;
            sec.PageSetup.Margins.Left = 36;

            sec.PageSetup.HeaderDistance = sec.PageSetup.FooterDistance = 14f;

            sec.PageSetup.ColumnsLineBetween = true;

            if (radioEncodeCol2.Checked)
            {
                sec.AddColumn(100f, 20f);
                sec.AddColumn(100f, 20f);
            }
            else if (radioEncodeCol3.Checked)
            {
                sec.AddColumn(100f, 20f);
                sec.AddColumn(100f, 20f);
                sec.AddColumn(100f, 20f);
            }

            if (chekbxEncodeFooter.Checked)
            {
                ParagraphStyle footerStyle = new ParagraphStyle(docNodes);
                footerStyle.Name = "footerStyle";
                footerStyle.CharacterFormat.Font = new Font("Times", 12, FontStyle.Bold);
                footerStyle.CharacterFormat.FontSize = 12;
                footerStyle.CharacterFormat.FontSizeBidi = 12;
                footerStyle.CharacterFormat.Bidi = true;
                footerStyle.ParagraphFormat.IsBidi = true;
                docNodes.Styles.Add(footerStyle);

                HeaderFooter footer = sec.HeadersFooters.Footer;
                Table footerTbl = footer.AddTable();
                footerTbl.ResetCells(1, 2);
                footerTbl.TableFormat.CellSpacing = 0;
                footerTbl.TableFormat.Paddings.All = 0;
                footerTbl.TableFormat.HorizontalAlignment = RowAlignment.Center;
                footerTbl.TableFormat.LayoutType = LayoutType.AutoFit;
                footerTbl.AutoFit(AutoFitBehaviorType.AutoFitToWindow);
                footerTbl.Rows[0].Cells[0].Width = 60f;

                if (chekbxEncodePageNumber.Checked)
                {
                    Paragraph pageNumber = footerTbl.Rows[0].Cells[0].AddParagraph();
                    pageNumber.AppendField("page number", FieldType.FieldPage);                   
                    pageNumber.AppendText("Page ");
                    pageNumber.Format.HorizontalAlignment = Spire.Doc.Documents.HorizontalAlignment.Right;
                    pageNumber.ApplyStyle(footerStyle.Name);
                }
                if (chekbxEncodeDetails.Checked)
                {
                    Paragraph modelDetails = footerTbl.Rows[0].Cells[1].AddParagraph();
                    if (txtMapName.Text.Replace(" ", "") != string.Empty)
                    {
                        modelDetails.AppendText("Map name:  " + txtModelName.Text + "         ");
                    }
                    modelDetails.ApplyStyle(footerStyle.Name);
                }
            }
            ParagraphStyle nodesStyle = new ParagraphStyle(docNodes);
            nodesStyle.Name = "nodesStyle";
            nodesStyle.CharacterFormat.Font = new Font("Times", 12, FontStyle.Bold);
            nodesStyle.CharacterFormat.FontSize = 12;
            nodesStyle.CharacterFormat.FontSizeBidi = 12;
            nodesStyle.ParagraphFormat.HorizontalAlignment = Spire.Doc.Documents.HorizontalAlignment.Justify;
            docNodes.Styles.Add(nodesStyle);

            ParagraphStyle nodeCountStyle = new ParagraphStyle(docNodes);
            nodeCountStyle.Name = "nodeCountStyle";
            nodeCountStyle.CharacterFormat.Font = new Font("Times", 10, FontStyle.Regular);
            nodeCountStyle.CharacterFormat.FontSize = 10;
            nodeCountStyle.CharacterFormat.FontSizeBidi = 10;
            nodeCountStyle.ParagraphFormat.HorizontalAlignment = Spire.Doc.Documents.HorizontalAlignment.Center;
            docNodes.Styles.Add(nodeCountStyle);

            ParagraphStyle gapStyle = new ParagraphStyle(docNodes);
            gapStyle.Name = "gapStyle";
            gapStyle.CharacterFormat.FontSize = 6;
            gapStyle.CharacterFormat.FontSizeBidi = 6;
            docNodes.Styles.Add(gapStyle);

            for (int i = int.Parse(txtLayerFrom.Text) - 1; i < int.Parse(txtLayerTo.Text); i++)
            {
                Paragraph nodesParaghraph = sec.AddParagraph();
                nodesParaghraph.AppendText("Layer " + (i + 1).ToString());
                nodesParaghraph.Format.HorizontalAlignment = Spire.Doc.Documents.HorizontalAlignment.Center;
                nodesParaghraph.Format.BackColor = Color.FromArgb(192, 192, 192);
                nodesParaghraph.Format.IsBidi = true;
                nodesParaghraph.ApplyStyle(nodesStyle.Name);

                Table tbl = sec.AddTable();
                tbl.ResetCells(1, 3);
                tbl.TableFormat.LayoutType = LayoutType.AutoFit;
                tbl.AutoFit(AutoFitBehaviorType.AutoFitToContents);
                tbl.TableFormat.Paddings.Left = 3;
                tbl.TableFormat.Paddings.Right = 3;

                tbl.LastRow.Cells[0].CellFormat.Borders.Bottom.BorderType = Spire.Doc.Documents.BorderStyle.Single;
                tbl.LastRow.Cells[1].CellFormat.Borders.Bottom.BorderType = Spire.Doc.Documents.BorderStyle.Single;
                tbl.LastRow.Cells[2].CellFormat.Borders.Bottom.BorderType = Spire.Doc.Documents.BorderStyle.Single;
                for (int j = 0; j < layerNodes[i].Count; j++)
                {
                    if (layerNodes[i][j].Count > 0)
                    {
                        nodesParaghraph = tbl.LastRow.Cells[0].AddParagraph();
                        nodesParaghraph.AppendText((j + 1).ToString() + ":");
                        nodesParaghraph.ApplyStyle(nodesStyle.Name);

                        nodesParaghraph = tbl.LastRow.Cells[1].AddParagraph();
                        nodesParaghraph.AppendText(layerNodes[i][j].Count.ToString());
                        nodesParaghraph.Format.LineSpacingRule = LineSpacingRule.Exactly;
                        nodesParaghraph.Format.LineSpacing = 12;
                        nodesParaghraph.ApplyStyle(nodeCountStyle.Name);
                        nodesParaghraph = tbl.LastRow.Cells[1].AddParagraph();
                        nodesParaghraph.AppendText("nodes");
                        nodesParaghraph.Format.LineSpacing = 6f;
                        nodesParaghraph.ApplyStyle(nodeCountStyle.Name);

                        string nodes = (layerNodes[i][j][0] + 1).ToString();
                        string space = "   ";
                        nodesParaghraph = tbl.LastRow.Cells[2].AddParagraph();
                        if (layerNodes[i][j].Count < 3)
                        {
                            for (int k = 1; k < layerNodes[i][j].Count; k++)
                            {
                                nodes += space + (layerNodes[i][j][k] + 1);
                            }
                        }
                        else
                        {
                            for (int k = 1; k < layerNodes[i][j].Count - 1; k++)
                            {
                                if (layerNodes[i][j][k] == (layerNodes[i][j][k - 1] + 1) && layerNodes[i][j][k] == (layerNodes[i][j][k + 1] - 1))
                                    space = "-";
                                else
                                {
                                    nodes += space + (layerNodes[i][j][k] + 1);
                                    space = "   ";
                                }
                            }
                            nodes += space + (layerNodes[i][j][layerNodes[i][j].Count - 1] + 1);
                        }
                        nodesParaghraph.AppendText(nodes);
                        nodesParaghraph.ApplyStyle(nodesStyle.Name);

                        tbl.AddRow();
                    }
                }
                tbl.Rows.Remove(tbl.LastRow);
                tbl.LastRow.Cells[0].CellFormat.Borders.Bottom.BorderType = Spire.Doc.Documents.BorderStyle.None;
                tbl.LastRow.Cells[1].CellFormat.Borders.Bottom.BorderType = Spire.Doc.Documents.BorderStyle.None;
                tbl.LastRow.Cells[2].CellFormat.Borders.Bottom.BorderType = Spire.Doc.Documents.BorderStyle.None;

                if (!chekbxEncodeContinuous.Checked)
                {
                    nodesParaghraph.AppendBreak(BreakType.PageBreak);
                }
                else
                {
                    nodesParaghraph = sec.AddParagraph();
                    nodesParaghraph.ApplyStyle(gapStyle.Name);
                }
                progressBar1.Invoke((MethodInvoker)delegate
                {
                    progressBar1.Value++;
                });
            }
            return docNodes;
        }


Since your website doesn't allow attaching of files with more than 2MB of size, I've uploaded output file to my server and here is the download link:
» jalali.dev/spire_doc/map%20EA67-b.zip

Need to mention that for the file I'm sending to you I've tried to decrease font size and spacing between lines and etc, therefore page count decreased to 1223,
but still it takes around 30 seconds to save the file.
And as I mentioned before, the time required for saving increases dramatically when page count reaches around 2000.

Extra info:
It takes 24-25 seconds to calculate and prepare docNodes variable for saving (plus saving time, it takes 55-60 seconds in total),
and while saving, usage of RAM increases to a cap of 2.7GB for this specific image.


Again, thank you a lot for your attention and helping me on solving this problem.

Leviamatte
 
Posts: 6
Joined: Sat Apr 17, 2021 2:20 pm

Tue Apr 20, 2021 11:08 am

Hello,

Thanks for sharing more information!

Since the code you provided cannot be run directly and the main operation you did in the code is to add lots of custom-style table to the Word document. I modified some parts of your code to make it run, and simulated to generate 1422 pages of Word Document which contains 1700 no-style tables. During the testing, the consumed memory was more than 5 GB, and the storage time did take too long.

I have logged the issue of excessive memory consumption and long storage time in our issue tracking system with the ticket SPIREDOC-5873 for further investigation.

We will let you know if there is any update. Sorry for the inconvenience caused.

Besides, if you have purchased our product, could you please provide us with your order number or purchase email? Thanks in advance.

Sincerely,
Marcia
E-iceblue support team
User avatar

Marcia.Zhou
 
Posts: 408
Joined: Wed Nov 04, 2020 2:29 am

Tue Apr 20, 2021 3:54 pm

Hello,

Thank you for attending to this problem.

For now I'm using the free version of Spire.Doc that adds a red text on top of the document that later after saving the file, I delete it by hand :? :) :o
This is my first project that I'm dealing with document files and I was testing different libraries that I found yours a powerful one and continued with it.

Thanks for the support.
I hope this problem will be solved.

Leviamatte
 
Posts: 6
Joined: Sat Apr 17, 2021 2:20 pm

Wed Apr 21, 2021 1:32 am

Hello,

Thanks for your feedback!

Once there is any progress regarding the issue SPIREDOC-5873, we will notify you immediately.

Sincerely,
Marcia
E-iceblue support team
User avatar

Marcia.Zhou
 
Posts: 408
Joined: Wed Nov 04, 2020 2:29 am

Return to Spire.Doc