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

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


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 2022-12-30.

benchmark graphic

    Time Memory File size
hexapdf 1x 491ms 43.316KiB 441.386
prawn 1x 586ms 36.360KiB 616.765
reportlab/C 1x 239ms 28.096KiB 474.492
fpdf2 1x 193ms 27.544KiB 483.815
jPDFWriter 1x 441ms 113.128KiB 569.421
tcpdf 1x 715ms 32.116KiB 627.074
PDF::API2 1x 756ms 31.000KiB 455.301
pdfkit 1x 1.279ms 66.680KiB 637.581
hexapdf 5x 1.476ms 53.448KiB 2.201.631
prawn 5x 2.041ms 53.800KiB 3.084.301
reportlab/C 5x 659ms 44.308KiB 2.372.212
fpdf2 5x 521ms 39.720KiB 2.419.973
jPDFWriter 5x 858ms 153.340KiB 2.849.342
tcpdf 5x 3.302ms 47.432KiB 3.112.669
PDF::API2 5x 3.872ms 45.604KiB 2.276.976
pdfkit 5x 4.293ms 101.172KiB 3.189.607
hexapdf 10x 2.882ms 65.120KiB 4.403.278
prawn 10x 3.851ms 74.456KiB 6.170.089
reportlab/C 10x 1.283ms 65.116KiB 4.745.535
fpdf2 10x 989ms 55.868KiB 4.841.427
jPDFWriter 10x 1.514ms 259.004KiB 5.700.015
tcpdf 10x 6.690ms 65.672KiB 6.221.294
PDF::API2 10x 8.912ms 63.448KiB 4.555.381
pdfkit 10x 8.284ms 123.036KiB 6.380.272
hexapdf 1x ttf 591ms 41.152KiB 535.239
prawn 1x ttf 1.949ms 40.648KiB 636.143
reportlab/C 1x ttf 481ms 33.164KiB 623.813
fpdf2 1x ttf 466ms 34.504KiB 588.036
ERR jPDFWriter 1x ttf 0ms 0KiB 0
tcpdf 1x ttf 884ms 37.368KiB 758.153
PDF::API2 1x ttf 6.966ms 52.220KiB 668.730
pdfkit 1x ttf 2.078ms 103.352KiB 726.257
hexapdf 5x ttf 1.846ms 55.028KiB 2.615.336
prawn 5x ttf 8.438ms 56.000KiB 3.098.169
reportlab/C 5x ttf 1.936ms 56.836KiB 3.037.994
fpdf2 5x ttf 1.792ms 49.368KiB 2.855.182
ERR jPDFWriter 5x ttf 0ms 0KiB 0
tcpdf 5x ttf 4.128ms 54.652KiB 3.573.805
PDF::API2 5x ttf 34.203ms 76.288KiB 3.083.900
pdfkit 5x ttf 4.622ms 124.748KiB 3.568.200
hexapdf 10x ttf 3.451ms 73.516KiB 5.217.075
prawn 10x ttf 16.769ms 76.476KiB 6.177.034
reportlab/C 10x ttf 3.746ms 86.748KiB 6.056.934
fpdf2 10x ttf 3.417ms 68.292KiB 5.690.736
ERR jPDFWriter 10x ttf 0ms 0KiB 0
tcpdf 10x ttf 8.137ms 77.220KiB 7.095.073
PDF::API2 10x ttf 68.832ms 106.580KiB 6.104.392
pdfkit 10x ttf 7.819ms 147.540KiB 7.120.880