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


Language: Python
Version: 3.5.6

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


Language: Perl
Version: 2.033


Language: Javascript
Version: 0.8.3


These benchmark results are from 2018-12-31.

benchmark graphic

    Time Memory File size
hexapdf 1x 443ms 24.448KiB 452.597
prawn 1x 389ms 20.884KiB 616.765
reportlab 1x 310ms 22.908KiB 474.492
reportlab/C 1x 207ms 25.024KiB 474.492
jPDFWriter 1x 376ms 111.988KiB 569.421
tcpdf 1x 646ms 33.240KiB 626.715
PDF::API2 1x 694ms 30.012KiB 462.284
pdfkit 1x 1.645ms 141.052KiB 637.241
hexapdf 5x 1.584ms 37.656KiB 2.258.903
prawn 5x 1.330ms 40.656KiB 3.084.301
reportlab 5x 1.271ms 47.028KiB 2.372.212
reportlab/C 5x 650ms 42.984KiB 2.372.212
jPDFWriter 5x 751ms 156.784KiB 2.849.342
tcpdf 5x 3.014ms 46.112KiB 3.112.310
PDF::API2 5x 3.325ms 44.816KiB 2.299.595
pdfkit 5x 5.721ms 376.092KiB 3.189.257
hexapdf 10x 3.075ms 49.656KiB 4.517.824
prawn 10x 2.607ms 66.744KiB 6.170.089
reportlab 10x 2.489ms 75.744KiB 4.745.535
reportlab/C 10x 1.250ms 66.232KiB 4.745.535
jPDFWriter 10x 1.407ms 264.676KiB 5.700.015
tcpdf 10x 5.863ms 64.436KiB 6.220.935
PDF::API2 10x 8.575ms 62.892KiB 4.597.516
pdfkit 10x 11.348ms 663.388KiB 6.379.922
hexapdf 1x ttf 500ms 23.968KiB 549.521
prawn 1x ttf 837ms 24.048KiB 636.184
reportlab 1x ttf 520ms 28.328KiB 623.810
reportlab/C 1x ttf 427ms 29.908KiB 623.810
ERR jPDFWriter 1x ttf 0ms 0KiB 0
tcpdf 1x ttf 822ms 36.368KiB 757.794
PDF::API2 1x ttf 6.273ms 50.832KiB 668.753
pdfkit 1x ttf 2.182ms 179.572KiB 725.810
hexapdf 5x ttf 1.959ms 44.948KiB 2.687.121
prawn 5x ttf 3.689ms 44.208KiB 3.098.210
reportlab 5x ttf 2.333ms 59.344KiB 3.037.991
reportlab/C 5x ttf 1.724ms 55.812KiB 3.037.991
ERR jPDFWriter 5x ttf 0ms 0KiB 0
tcpdf 5x ttf 3.768ms 53.568KiB 3.573.446
PDF::API2 5x ttf 29.988ms 75.404KiB 3.083.923
pdfkit 5x ttf 5.528ms 476.564KiB 3.567.743
hexapdf 10x ttf 3.853ms 61.596KiB 5.360.948
prawn 10x ttf 7.183ms 66.216KiB 6.177.075
reportlab 10x ttf 4.619ms 97.304KiB 6.056.931
reportlab/C 10x ttf 3.349ms 88.064KiB 6.056.931
ERR jPDFWriter 10x ttf 0ms 0KiB 0
tcpdf 10x ttf 7.429ms 75.344KiB 7.094.714
PDF::API2 10x ttf 63.980ms 105.636KiB 6.104.415
pdfkit 10x ttf 10.237ms 844.932KiB 7.120.423