Simple Text Rendering Benchmark

The Python PDF generation library ReportLab contains a demo/benchmarking application that takes the Project Gutenberg text of Homer’s Odyssey (contains about 12.000 lines and about 700.000 characters) and creates a PDF version from it. This benchmark is derived from that demo.

No advanced text features are used or needed by this benchmark, only the raw text output performance is tested.

Benchmark Setup

The text of the Odyssey is written onto A4 pages with a margin of 72 points, showing each line of the source text using the most basic text drawing methods available, without line wrapping or text measuring.

To see how the amount of text influences the performance, the benchmark is done by concatenating the text multiple times (1x, 5x and 10x by default). Additionally, all multiplication factors are combined once with the standard PDF Type1 font Times-Roman and once with a TrueType font (DejaVu Sans by default).

Each benchmark script (except the jPDFWriter and pdfkit ones) can be invoked standalone in the following way: script-executable TXT_FILE OUTPUT_FILE [TTF_FILE].

The list of the benchmarked libraries:


Language: Ruby
Version: Latest version


Language: Ruby
Version: 2.3.0


Language: Python
Version: 3.5.23

ReportLab has a module that implements some features in C to speed up the execution. Both versions are used in the benchmark.


Language: Java
Version: v2016R1

Qoppa Software provides the free jPDFWriter library which is needed for benchmarking this library. The Java source code file for the benchmark needs to be compiled and the jPDFWriter-JAR put onto the CLASSPATH environment variable.

Note that TrueType fonts don’t seem to be supported.


Language: PHP
Version: 6.3.5


Language: Perl
Version: 2.037


Language: Javascript
Version: 0.11.0


These benchmark results are from 2020-12-27.

benchmark graphic

    Time Memory File size
hexapdf 1x 557ms 34.160KiB 452.598
prawn 1x 419ms 31.596KiB 585.793
reportlab 1x 186ms 22.816KiB 474.492
reportlab/C 1x 197ms 24.940KiB 474.492
jPDFWriter 1x 419ms 112.488KiB 569.421
tcpdf 1x 660ms 29.872KiB 627.074
PDF::API2 1x 679ms 31.408KiB 458.384
pdfkit 1x 1.265ms 74.888KiB 637.581
hexapdf 5x 1.891ms 45.244KiB 2.258.904
prawn 5x 1.467ms 49.956KiB 2.929.789
reportlab 5x 711ms 46.876KiB 2.372.212
reportlab/C 5x 626ms 40.952KiB 2.372.212
jPDFWriter 5x 870ms 157.256KiB 2.849.342
tcpdf 5x 3.221ms 44.748KiB 3.112.669
PDF::API2 5x 3.514ms 45.684KiB 2.280.059
pdfkit 5x 3.713ms 117.140KiB 3.189.607
hexapdf 10x 3.754ms 57.364KiB 4.517.825
prawn 10x 2.874ms 71.540KiB 5.861.065
reportlab 10x 1.455ms 75.672KiB 4.745.535
reportlab/C 10x 1.211ms 61.748KiB 4.745.535
jPDFWriter 10x 1.468ms 254.972KiB 5.700.015
tcpdf 10x 6.457ms 63.192KiB 6.221.294
PDF::API2 10x 8.685ms 63.768KiB 4.558.464
pdfkit 10x 6.880ms 146.340KiB 6.380.272
hexapdf 1x ttf 634ms 33.044KiB 549.522
prawn 1x ttf 996ms 34.000KiB 605.210
reportlab 1x ttf 520ms 27.948KiB 623.810
reportlab/C 1x ttf 434ms 29.996KiB 623.810
ERR jPDFWriter 1x ttf 0ms 0KiB 0
tcpdf 1x ttf 872ms 34.608KiB 758.153
PDF::API2 1x ttf 6.533ms 52.768KiB 668.753
pdfkit 1x ttf 2.081ms 112.336KiB 726.254
hexapdf 5x ttf 2.335ms 48.908KiB 2.687.124
prawn 5x ttf 4.295ms 50.860KiB 2.943.696
reportlab 5x ttf 2.249ms 59.008KiB 3.037.991
reportlab/C 5x ttf 1.859ms 53.880KiB 3.037.991
ERR jPDFWriter 5x ttf 0ms 0KiB 0
tcpdf 5x ttf 4.177ms 52.008KiB 3.573.805
PDF::API2 5x ttf 32.806ms 76.952KiB 3.083.923
pdfkit 5x ttf 4.580ms 136.300KiB 3.568.197
hexapdf 10x ttf 4.693ms 63.568KiB 5.360.947
prawn 10x ttf 9.013ms 74.240KiB 5.868.049
reportlab 10x ttf 4.571ms 96.844KiB 6.056.931
reportlab/C 10x ttf 3.633ms 83.504KiB 6.056.931
ERR jPDFWriter 10x ttf 0ms 0KiB 0
tcpdf 10x ttf 8.258ms 74.600KiB 7.095.073
PDF::API2 10x ttf 68.445ms 107.620KiB 6.104.415
pdfkit 10x ttf 7.197ms 170.192KiB 7.120.877