Performance considerations
Generating a QR Code is not a trivial task - it is a combination of countless complex mathematical operations on top of rendering the output.
This library seeks not to be the fastest QR Code generator, but instead to provide flexibility and user friendlyness, which in turn comes with a slight performance cost.
Version
The version of the QR symbol is one of the major performance factors as it determines the size of the symbol and therefore the amount of data that can be stored. Iterating over the internal representation of the matrix takes more time with increasing size and the internals iterate over the matrix a LOT.
Because of that, you want to select the smallest possible version for the given data of course, which the encoder does by default. However, sometimes the possibly varying size of the symbol may not be desired and you want to choose a fixed size, in which case you should determine the maximum size of the input data and choose a version that fits.
Ecc level
Another factor is the ECC level that determines the error correction capacity. The default setting is the lowest capacity (L, 7%) which allows the highest amount of data to be stored and which is good enough for e.g. on-screen display or poster prints. ECC level H on the other hand allows for up to 30% error correction capacity, which is great for “high risk” applications such as prints on mail. With increasing error correction capacity, the maximum amount of data a symbol can hold decreases, and a higher version number may be necessary.
Data mode
By default, the encoder auto-detects the best mode for data encoding (numeric, alphanumeric, kanji, hanzi or 8-bit binary)
and depending on the length of the given data, the detection costs an increasing amount of time. To circumvent this,
you can call one of the “add segment” methods on the QRCode
instance, for example: $qrcode->addByteSegment($data)
.
Generally, using 8-bit binary mode (or just “byte mode”) is the fast and fail-safe mode for any kind of data, and with ECI it even offers support for character sets other than UTF-8. So, unless you want to fit a large amount of japanese or chinese characters into a QR symbol of a certain version, encoding those characters as 3 or 4 byte UTF-8 may still be faster in 8-bit byte than in the “compressed” 13-bit double byte modes.
Mask pattern
Evaluating the QR symbol in order to pick the right mask pattern is a complex and costly operation that is necessary to ensure the symbol is readable. Although there is an option to override the evaluation and manually set a mask pattern, this is not recommended unless you know exactly what you’re doing as it can render a QR symbol unreadable.
The table below shows the performance impact (in miliseconds) of the mask pattern evaluation for each version, the times may vary between systems.
version |
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
---|---|---|---|---|---|---|---|---|---|---|
1-10 |
4.414 |
5.697 |
7.986 |
9.221 |
10.877 |
11.293 |
13.901 |
15.563 |
18.142 |
20.501 |
11-20 |
22.662 |
27.779 |
29.622 |
33.017 |
36.358 |
39.712 |
43.685 |
47.121 |
51.389 |
57.865 |
21-30 |
59.753 |
68.502 |
68.523 |
72.866 |
78.245 |
83.593 |
88.327 |
94.921 |
103.394 |
106.358 |
31-40 |
113.311 |
120.484 |
126.215 |
132.931 |
139.783 |
145.617 |
170.576 |
165.996 |
167.365 |
175.821 |
Output
Output rendering depends heavily on the size of the QR matrix, the desired type and the underlying libraries and/or PHP extensions. Especially the rendering of raster images through GD or ImagMagick can be very slow, depending on the scale setting, filters and image type.
Below a comparison of the performance for the several built-in output classes (times in miliseconds, scale = 5):
v5 |
v10 |
v15 |
v20 |
v25 |
v30 |
v35 |
v40 |
|
---|---|---|---|---|---|---|---|---|
QRMarkupSVG |
3.732 |
8.645 |
13.846 |
21.127 |
32.842 |
43.753 |
56.584 |
73.885 |
QRMarkupHTML |
0.522 |
1.308 |
2.062 |
2.761 |
3.907 |
5.201 |
7.931 |
9.572 |
QRGdImageBMP |
5.998 |
12.541 |
20.728 |
32.336 |
46.345 |
62.842 |
81.555 |
106.482 |
QRGdImageGIF |
3.427 |
6.817 |
12.226 |
17.925 |
25.453 |
35.136 |
44.706 |
57.477 |
QRGdImageJPEG |
2.284 |
4.882 |
8.161 |
12.097 |
17.333 |
23.862 |
30.327 |
40.226 |
QRGdImagePNG |
4.523 |
9.377 |
16.581 |
26.207 |
36.516 |
49.066 |
63.765 |
82.074 |
QRGdImageWEBP |
8.211 |
17.367 |
30.079 |
47.095 |
69.668 |
91.378 |
119.869 |
150.288 |
QRStringJSON |
0.043 |
0.066 |
0.107 |
0.158 |
0.215 |
0.301 |
0.369 |
0.492 |
QRStringText |
0.229 |
0.387 |
0.628 |
0.952 |
1.312 |
1.759 |
2.329 |
3.045 |
QRImagick |
37.694 |
68.808 |
114.415 |
172.962 |
242.338 |
325.085 |
419.999 |
529.897 |
QRFpdf |
6.578 |
12.466 |
21.169 |
33.021 |
45.469 |
61.198 |
80.092 |
100.059 |
QREps |
1.269 |
2.694 |
4.515 |
6.933 |
11.049 |
14.181 |
20.799 |
25.886 |