Performance Best Practices
Several decisions make document processing with TX Text Control .NET Server measurably faster, and Text Control has published benchmarks for most of them. Each recommendation comes with its numbers and the conditions they were measured under, so that you can judge which ones matter for your documents, and with a link to the page that shows the code. The last one matters most: measure with your own templates and data.
At a Glance
| Practice | Effect | Read |
|---|---|---|
| Use the Core engine | PDF from plain text up to 11 times faster than with the Classic engine | Use the Core Engine |
| Build text with Selection objects | About twice as fast as inserting, selecting and formatting | Build Text With Selection Objects |
| Keep documents in the TX Text Control format while they change | No conversion when loading and saving | Keep the Internal Format Until the End |
| Return short jobs, queue long ones | A typical invoice in about 300 ms | Keep Requests Short |
| Keep processing apart from editing | Editing sessions stay responsive under load | Separate Processing From Editing |
| Use processes for large batches | 100 merges about three times faster in parallel processes | Multiple Processes |
| Compress images in PDF documents | 14.68 MB down to 1.48 MB in a test document | Keep Documents Small |
| Measure your own workload | Every benchmark depends on its documents and hardware | Measure Your Own Workload |
Use the Core Engine
The Core engine, TXTextControl.TextControl.Core.SDK, was faster than the Classic engine in both of Text Control's published comparisons. In the first, a text with one GUID per line was loaded into ServerTextControl and saved as DOCX and PDF:
| Lines | Core, DOCX | Core, PDF | Classic, DOCX | Classic, PDF |
|---|---|---|---|---|
| 100 | 11 ms | 23 ms | 51 ms | 214 ms |
| 5,000 | 113 ms | 684 ms | 289 ms | 7,842 ms |
| 100,000 (1,588 pages) | 3,047 ms | 14,518 ms | 5,885 ms | 159,313 ms |
A second benchmark compared individual operations, averaged over five runs:
| Operation | Classic on Windows | Core on Windows | Core on Linux |
|---|---|---|---|
| A table with 500 rows and 10 columns, filled with text | 11,297 ms | 7,476 ms | 7,321 ms |
| Inserting 500 images | 952 ms | 40 ms | 34 ms |
| 500 formatting operations | 1,783 ms | 86 ms | 96 ms |
Neither article names the hardware. The blog articles TX Text Control Core vs. Classic Performance Comparison Plain Text to DOCX and PDF and Benchmarking TX Text Control: Classic vs. Core on Windows and Linux contain the code.
Processing time turns into server time. Text Control projects from these timings that 10,000 PDF documents of the 5,000-line size, created one after another, take 21.8 hours with Classic and 1.9 hours with Core. The blog article From Milliseconds to Cloud Costs: The Real Impact of Faster Document Processing in C# .NET calls these projections, not production measurements, and lists what changes real results. The Classic engine remains the choice for applications that must load or save DOC files or stay with an existing Classic integration, as The Document Engine explains.
Build Text With Selection Objects
A document built in code from many paragraphs is faster when each piece of text arrives with its formatting: a new Selection object with Text, FontName and FontSize assigned to ServerTextControl.Selection inserts formatted text in one step. Inserting the text, selecting it with Select and formatting it afterward takes three.
In Text Control's measurements with the Core engine, documents with 10 sections and 10 to 100 paragraphs per section took 5.7 to 42.9 ms each with Selection objects and 10.6 to 88.9 ms with insert, select and format: about twice as long. The article doesn't name the hardware either. Insert Formatted Text shows the code, and the blog article Speed Up Document Generation by Factor 2 Using Selection Objects in .NET C# the measurements.
Keep the Internal Format Until the End
The TX Text Control format, StreamType.InternalUnicodeFormat, is the format of the engine itself. Text Control recommends it for every step of a document's life in which the document still changes: templates are designed in it, merged without leaving it and edited and reviewed in it. Loading and saving it needs no conversion, and it supports every feature of TX Text Control. The Document Editor saves it with TXTextControl.StreamType.InternalUnicodeFormat, and the DataRowMerged event of MailMerge delivers merged documents in it. Text Control publishes no measurements for this recommendation; the blog article Document Lifecycle Optimization: Leveraging TX Text Control's Internal Format describes the workflow.
Convert a document to PDF once, when it's final: a PDF that is created before the data and approvals are complete has to be created again. Create PDF Documents Efficiently in PDF Creation summarizes this.
Keep Requests Short
A typical invoice is created in about 300 ms, and an HTTP request can return it directly. Documents that take several seconds, such as merges with many nested merge blocks and thousands of pages, are better accepted by the endpoint, created by a background service and announced when they're ready. For long-running work in ASP.NET Core, Microsoft recommends the BackgroundService base class. Keep the Service Responsive in REST Services describes the pattern, and Merge Documents With Thousands of Pages the design of long merge templates.
Separate Processing From Editing
Editing sessions of the Document Editor need a predictable amount of memory, while document processing needs an unpredictable amount of CPU. In one application, heavy processing can block the WebSocket connections of the editors. With many concurrent users, Text Control recommends a separate application for PDF generation, batch mail merges and conversions, which scales on its own. Container Scaling describes how each part scales.
Measure Your Own Workload
Text Control publishes no fixed maximum number of ServerTextControl instances or documents per second for a server, and the benchmarks above name little of their hardware. Your templates, data, images and fonts decide the numbers. The following program measures the three steps of a merge separately, so that you know which one to improve. It expects a template template.docx and a data file data.json in the folder of the application, as in Simple Mail Merge:
using System.Diagnostics;
using TXTextControl;
using TXTextControl.DocumentServer;
string jsonData = File.ReadAllText("data.json");
Stopwatch stopwatch = Stopwatch.StartNew();
using (ServerTextControl tx = new ServerTextControl())
{
tx.Create();
LoadSettings loadSettings = new LoadSettings
{
ApplicationFieldFormat = ApplicationFieldFormat.MSWord,
LoadSubTextParts = true
};
tx.Load("template.docx", StreamType.WordprocessingML, loadSettings);
Console.WriteLine($"Load: {stopwatch.ElapsedMilliseconds} ms");
stopwatch.Restart();
using (MailMerge mailMerge = new MailMerge { TextComponent = tx })
{
mailMerge.MergeJsonData(jsonData);
}
Console.WriteLine($"Merge: {stopwatch.ElapsedMilliseconds} ms");
stopwatch.Restart();
tx.Save("result.pdf", StreamType.AdobePDF);
Console.WriteLine($"Save: {stopwatch.ElapsedMilliseconds} ms");
}
The code works as follows:
StopwatchfromSystem.Diagnosticsmeasures the elapsed time, andRestartstarts each step at zero.- Load with the load settings imports the fields and merge blocks of the DOCX template, MergeJsonData merges the data and Save creates the PDF.
- Run the program several times and compare the later runs. Text Control's benchmark of Selection objects warms up every test before it measures it, and the Windows and Linux benchmark averages five runs.
Measure on hardware like your production servers, with the documents your users create. Multiple Processes describes how to find the number of parallel workers that gives the highest throughput.
Next Steps
- Large Documents: viewer streaming, request size limits and long merges.
- Multiple Processes: process large batches in parallel worker processes.
- Memory Usage: what documents and editing sessions need in memory.
- Container Scaling: size the instances of each workload.