Browse Source

Text Rendering Optimization: Caching Measurement Results

Marcin Ziąbek 4 years ago
parent
commit
5f65b2daed

+ 3 - 7
QuestPDF.Examples/TextBenchmark.cs

@@ -22,17 +22,13 @@ namespace QuestPDF.Examples
             var normalStyle = TextStyle.Default.Size(14);
             
             var chapters = GetChapters().ToList();
-
-            var results = PerformTest(1).ToList();
-            
-            var a = CanvasCache.Paints;
-            
+  
+            var results = PerformTest(16).ToList();
+ 
             Console.WriteLine($"Min: {results.Min():F}");
             Console.WriteLine($"Max: {results.Max():F}");
             Console.WriteLine($"Avg: {results.Average():F}");
 
-            
-
             IEnumerable<(string title, string content)> GetChapters()
             {
                 var book = File.ReadAllLines("quo-vadis.txt");

+ 29 - 0
QuestPDF.Examples/optimization.md

@@ -89,4 +89,33 @@ Results:
 Min: 13421,00
 Max: 14489,00
 Avg: 13606,81
+```
+
+## Caching Text Measurement Results
+
+```
+Attempt 0: 2507,00
+Attempt 1: 2022,00
+Attempt 2: 2033,00
+Attempt 3: 2034,00
+Attempt 4: 2061,00
+Attempt 5: 2058,00
+Attempt 6: 2056,00
+Attempt 7: 2035,00
+Attempt 8: 2042,00
+Attempt 9: 2348,00
+Attempt 10: 2650,00
+Attempt 11: 2503,00
+Attempt 12: 2423,00
+Attempt 13: 2084,00
+Attempt 14: 2064,00
+Attempt 15: 2044,00
+```
+
+Results:
+
+```
+Min: 2022,00
+Max: 2650,00
+Avg: 2185,25
 ```

+ 13 - 1
QuestPDF/Elements/Text/TextItem.cs

@@ -1,4 +1,5 @@
 using System;
+using System.Collections.Generic;
 using QuestPDF.Drawing;
 using QuestPDF.Drawing.SpacePlan;
 using QuestPDF.Infrastructure;
@@ -57,8 +58,16 @@ namespace QuestPDF.Elements.Text
         public string Text { get; set; }
         public TextStyle Style { get; set; } = new TextStyle();
 
+        private Dictionary<(int startIndex, float availableWidth), TextMeasurementResult?> MeasureCache =
+            new Dictionary<(int startIndex, float availableWidth), TextMeasurementResult?>();
+
         public TextMeasurementResult? Measure(TextMeasurementRequest request)
         {
+            var cacheKey = (request.StartIndex, request.AvailableWidth);
+            
+            if (MeasureCache.ContainsKey(cacheKey))
+                return MeasureCache[cacheKey];
+            
             var paint = Style.ToPaint();
             var fontMetrics = Style.ToFontMetrics();
             
@@ -85,7 +94,7 @@ namespace QuestPDF.Elements.Text
             // measure final text
             var width = paint.MeasureText(text);
             
-            return new TextMeasurementResult
+            var result = new TextMeasurementResult
             {
                 Width = width,
                 
@@ -98,6 +107,9 @@ namespace QuestPDF.Elements.Text
                 EndIndex = request.StartIndex + breakingIndex,
                 TotalIndex = Text.Length
             };
+
+            MeasureCache[cacheKey] = result;
+            return result;
         }
         
         public void Draw(TextDrawingRequest request)