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.4.0


Language: Python
Version: 3.6.12

ReportLab has a module that implements some features in C to speed up the execution. This module is used in the benchmark.


Language: Python
Version: 2.7.4


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.6.2


Language: Perl
Version: 2.044


Language: Javascript
Version: 0.11.0


These benchmark results are from 2023-08-03.

benchmark graphic

    Time Memory File size
hexapdf 1x 361ms 43.312KiB 441.386
prawn 1x 395ms 36.352KiB 616.765
reportlab/C 1x 144ms 31.488KiB 474.492
fpdf2 1x 234ms 51.056KiB 485.475
jPDFWriter 1x 362ms 93.880KiB 569.421
tcpdf 1x 461ms 33.272KiB 627.074
PDF::API2 1x 490ms 31.092KiB 455.322
pdfkit 1x 906ms 93.348KiB 637.581
hexapdf 5x 1.006ms 53.572KiB 2.201.635
prawn 5x 1.316ms 53.760KiB 3.084.301
reportlab/C 5x 406ms 48.512KiB 2.372.212
fpdf2 5x 485ms 63.724KiB 2.429.354
jPDFWriter 5x 657ms 189.072KiB 2.849.342
tcpdf 5x 2.060ms 48.220KiB 3.112.669
PDF::API2 5x 2.440ms 45.824KiB 2.276.997
pdfkit 5x 2.312ms 134.668KiB 3.189.607
hexapdf 10x 1.879ms 64.964KiB 4.403.276
prawn 10x 2.524ms 74.368KiB 6.170.089
reportlab/C 10x 752ms 70.324KiB 4.745.535
fpdf2 10x 809ms 79.816KiB 4.860.132
jPDFWriter 10x 954ms 277.588KiB 5.700.015
tcpdf 10x 4.106ms 66.492KiB 6.221.294
PDF::API2 10x 5.738ms 64.000KiB 4.555.402
pdfkit 10x 4.142ms 171.040KiB 6.380.272
hexapdf 1x ttf 401ms 41.472KiB 535.238
prawn 1x ttf 1.278ms 40.576KiB 636.144
reportlab/C 1x ttf 285ms 36.452KiB 623.814
fpdf2 1x ttf 444ms 57.436KiB 585.247
ERR jPDFWriter 1x ttf 0ms 0KiB 0
tcpdf 1x ttf 591ms 38.100KiB 758.153
PDF::API2 1x ttf 4.831ms 52.224KiB 668.754
pdfkit 1x ttf 1.497ms 140.912KiB 726.256
hexapdf 5x ttf 1.224ms 55.296KiB 2.615.336
prawn 5x ttf 5.614ms 56.320KiB 3.098.170
reportlab/C 5x ttf 1.042ms 60.904KiB 3.037.995
fpdf2 5x ttf 1.299ms 69.744KiB 2.860.114
ERR jPDFWriter 5x ttf 0ms 0KiB 0
tcpdf 5x ttf 2.792ms 55.584KiB 3.573.805
PDF::API2 5x ttf 23.469ms 76.288KiB 3.083.924
pdfkit 5x ttf 3.000ms 179.732KiB 3.568.199
hexapdf 10x ttf 2.286ms 73.600KiB 5.217.070
prawn 10x ttf 11.413ms 76.800KiB 6.177.035
reportlab/C 10x ttf 1.939ms 91.704KiB 6.056.935
fpdf2 10x ttf 2.339ms 91.368KiB 5.704.992
ERR jPDFWriter 10x ttf 0ms 0KiB 0
tcpdf 10x ttf 5.261ms 78.032KiB 7.095.073
PDF::API2 10x ttf 48.507ms 107.136KiB 6.104.416
pdfkit 10x ttf 5.167ms 210.680KiB 7.120.879