Performance is a critical factor for developers working with high-volume document creation and manipulation. As TX Text Control expands its capabilities with the new Core version, we decided to benchmark its performance against the Classic version on both Windows and Linux environments.

Based on the many changes required to port TX Text Control to Linux, we have significantly improved the performance of document processing. We took a bold step by developing a custom rendering foundation based entirely on SVG (Scalable Vector Graphics). This approach provides more control over the rendering process, ensuring high quality output and seamless cross-platform compatibility. By eliminating reliance on external libraries, the new system improves flexibility, performance, and long-term maintainability, making it a robust solution for rendering across multiple environments.

TX Text Control for Linux introduces a completely rewritten font rendering system to ensure cross-platform compatibility. Previously dependent on Windows-specific technologies, the new system is now platform-independent and delivers accurate, high-quality font rendering without sacrificing speed and efficiency.

Together, these enhancements deliver faster, more efficient, and highly scalable document processing. The purpose of this benchmark is to demonstrate the significant performance improvements.

Benchmark Setup

For our benchmark, we created a test suite that measures the execution time for various document operations. The test scenarios include:

  • Table insertion: Adding a large table (500 rows, 10 columns) and adding text to all table cells (5000 cells).
  • Image insertion: Inserting 500 images into a document.
  • Text formatting: Applying 500 random formatting manipulations.

The benchmarking tool was built as a C# console application using the Classic and Core versions of TX Text Control. The Core version has been tested on both Windows and Linux. The test was performed on a Windows 11 machine and a Linux Docker container. The system specifications are not relevant as the comparison between the two is important.

The benchmarking tool repeats the same test five times in a loop. The average execution time is then calculated.

Results

The following results show the average execution time for each test scenario:

Test Case Classic Windows) Core Windows Core Linux
Table insertion 11297ms 7476ms 7321ms
Image insertion 952ms 40ms 34ms
Text formatting 1783ms 86ms 96ms

The benchmark results show significant performance improvements with TX Text Control Core, demonstrating its efficiency across multiple operations.

Table insertion in TX Text Control Core showed a 33.8% reduction in execution time on Windows, dropping from 11297ms in TX Text Control Classic to 7476ms. On Linux, the performance was slightly better at 7321ms, a 35.2% improvement over TX Text Control Classic. This improvement is largely due to TX Text Control Core's optimized low-level drawing engine and better memory allocation strategies that allow for faster table rendering and data population.

Image insertion showed the most significant performance improvement. In TX Text Control Classic, inserting 5000 images took 952ms, while TX Text Control Core accomplished the same task in just 40ms on Windows and 34ms on Linux. This represents a 95.8% reduction in execution time on Windows and a 96.4% improvement on Linux.

Text formatting operations also showed impressive acceleration. TX Text Control Classic took 1783ms to perform 500 random formatting operations, while TX Text Control Core completed the same operation in just 86ms on Windows and 96ms on Linux. This represents a 95.2% reduction in execution time on Windows and a 94.6% improvement on Linux.

The following chart illustrates the percentage improvement of TX Text Control Core over the Classic version.

TX Text Control Linux Performance

The next figure shows how much faster the Core version is compared to the Classic version.

TX Text Control Linux Performance

Benchmark Test Classes

For full transparency, the following code snippets show the test classes that are used in the benchmarking tool:

using System.Diagnostics;
using System.Drawing;
using System.Security.Cryptography;
using TXTextControl;
class Benchmark
{
public enum TestType
{
Table,
Images,
Formatting
}
public const int Rows = 500;
public const int Cols = 10;
public const int Images = 500;
public const int Iterations = 5;
public double Run(TestType testType)
{
double totalTime = 0;
for (int i = 0; i < Iterations; i++)
{
using (ServerTextControl tx = new ServerTextControl())
{
tx.Create();
Stopwatch stopwatch = Stopwatch.StartNew();
switch (testType)
{
case TestType.Table:
TableInserter.InsertTable(tx);
break;
case TestType.Images:
// read image from file
byte[] imageBytes = File.ReadAllBytes("Images/signature2.png");
ImageInserter.InsertImages(tx, Images, imageBytes);
break;
case TestType.Formatting:
tx.Load("Documents/sample.tx", StreamType.InternalUnicodeFormat);
TextFormatter.ApplyRandomFormatting(tx, 500);
break;
}
stopwatch.Stop();
totalTime += stopwatch.ElapsedMilliseconds;
//tx.Save("results.pdf", StreamType.AdobePDF);
}
}
return totalTime / Iterations;
}
}
class TableInserter
{
public static void InsertTable(ServerTextControl tx)
{
tx.Tables.Add(Benchmark.Rows, Benchmark.Cols, 13);
Table table = tx.Tables.GetItem(13);
for (int r = 1; r < Benchmark.Rows; r++)
{
for (int c = 1; c < Benchmark.Cols; c++)
{
table.Cells[r, c].Text = $"Cell {r},{c}";
}
}
}
}
class ImageInserter
{
public static void InsertImages(ServerTextControl tx, int imageCount, byte[] imageBytes)
{
// publicly visible Memory stream for the image
using (MemoryStream ms = new MemoryStream(
imageBytes, 0, imageBytes.Length, writable: false, publiclyVisible: true))
{
for (int i = 0; i < imageCount; i++)
{
TXTextControl.Image img = new TXTextControl.Image(ms);
tx.Images.Add(img, -1);
}
}
}
}
class TextFormatter
{
public static void ApplyRandomFormatting(ServerTextControl tx, int manipulations)
{
int textLength = tx.Text.Length;
for (int i = 0; i < manipulations; i++)
{
int start = RandomUtil.GetSecureRandomNumber(0, textLength - 1);
int length = RandomUtil.GetSecureRandomNumber(1, Math.Min(10, textLength - start));
tx.Select(start, length);
tx.Selection.Bold = RandomUtil.GetSecureRandomBool();
if (RandomUtil.GetSecureRandomBool())
tx.Selection.GrowFont();
else
tx.Selection.ShrinkFont();
tx.Selection.ForeColor = RandomUtil.GetSecureRandomColor();
}
}
}
class RandomUtil
{
public static int GetSecureRandomNumber(int min, int max)
{
byte[] data = new byte[4];
RandomNumberGenerator.Fill(data);
int value = BitConverter.ToInt32(data, 0) & int.MaxValue;
return min + (value % (max - min + 1));
}
public static bool GetSecureRandomBool()
{
byte[] data = new byte[1];
RandomNumberGenerator.Fill(data);
return (data[0] & 1) == 1;
}
public static Color GetSecureRandomColor()
{
return Color.FromArgb(
GetSecureRandomNumber(0, 255),
GetSecureRandomNumber(0, 255),
GetSecureRandomNumber(0, 255)
);
}
}
view raw test.cs hosted with ❤ by GitHub

Conclusion

TX Text Control Core for Linux offers significant performance improvements over the Classic version, demonstrating its efficiency in various document operations. The new rendering foundation based on SVG and the platform-independent font rendering system have significantly improved the speed and efficiency of document processing. The benchmark results show that TX Text Control Core is a robust solution for high-volume document creation and manipulation, delivering faster, more efficient and highly scalable performance.