You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Performance enhancements are welcome, but significant gains are hard won.
819
-
820
-
Be aware that large 2D symbols have different runtime bottlenecks, for example:
821
-
822
-
**QR Code** - >60% of V40 runtime is mask evaluation; bottleneck is penalty calculation requiring multiple full-symbol scans; RSEC is fast
823
-
- Direct `masklayers` access (bitshift per pixel instead of extracting to array): Slower - per-pixel overhead in inner loops exceeds allocation savings
824
-
- Array reuse (preallocate `masksym`, `rle`, `lastpairs`, `thispairs`): No gain
825
-
826
-
**Data Matrix** - ~75% of 144x144 runtime is RSEC codeword calculation; bottleneck is due to many codewords per block
827
-
- ECC codeword calculation is already optimal so there is little that can be gained
828
-
- Generator polynomial generation is negligable compared to codeword calculation
829
-
830
-
**Aztec Code** - ~95% of 32-layer runtime is RSEC coefficient generation; bottleneck is large Galois field operations
831
-
- This cost is largely amortised during long production runs by using a FIFO cache
832
-
833
-
**PDF417** - At high ECC levels RSEC coefficient generation is ~85% of initial runtime
834
-
- This cost is largely amortised during long production runs by using a FIFO cache
835
-
836
-
**MicroPDF417** - No significant bottleneck
837
-
- Coefficient generation is quick due to limited number of error codewords
818
+
Performance enhancements are welcome, but significant gains are hard won. Large 2D symbols have different bottlenecks: QR Code is mask evaluation bound; Data Matrix, Aztec, and PDF417 are RSEC bound (mitigated by FIFO caches). See encoder source for attempted optimizations.
5. After CI succeeds: `make tag && git push origin YYYY-MM-DD`
1084
+
6. Verify release: `gh release view YYYY-MM-DD`
1085
+
7. Add next placeholder: `sed -i '1i XXXX-XX-XX\n\n*\n\n' CHANGES` and commit/push
1182
1086
1183
-
```postscript
1184
-
/dic 1 dict def % Initial size, should be sized appropriately; for static data, prefer next power of 2 above expected size
1185
-
dic /a 1 put
1186
-
dic /b 2 put % May overflow capacity, but is resized transparently (with associated performance impact)
1187
-
```
1188
-
1189
-
It is not possible to dynamically change the size of an existing array:
1190
-
1191
-
```postscript
1192
-
/arr 1 array def % Fixed size, should be sized appropriately
1193
-
arr 0 /a put % Indexed at zero
1194
-
arr 1 /b put % Error: Out of bounds write
1195
-
arr 1 get % Error: Out of bounds read
1196
-
```
1197
1087
1088
+
## PostScript Language Reminders
1198
1089
1199
-
Names and strings are treated as equivalent when compared:
1200
-
1090
+
**Stack operations:**
1201
1091
```postscript
1202
-
/test (test) eq => true
1092
+
(a) (b) (c) 3 1 roll => (c) (a) (b)
1093
+
(a) (b) (c) 3 -1 roll => (b) (c) (a)
1094
+
(a) (b) (c) 1 index => (a) (b) (c) (b)
1095
+
(a) (b) (c) /x 1 index def => x = (c), not (b) due to /x on stack!
1203
1096
```
1204
1097
1205
-
Understand that `readonly` does not affect its argument:
1206
-
1098
+
**`readonly` returns a new reference:**
1207
1099
```postscript
1208
1100
/a [ 1 2 3 ] def % a is writable
1209
-
a readonly pop % a is still writable; achieves nothing
1210
-
/c a readonly def % c is not writable; a remains writable
1211
-
```
1212
-
1213
-
Invalidating a boolean placed first on the stack is a common way to perform multiple tests that must pass:
1214
-
1215
-
```postscript
1216
-
true % Assume good until...
1217
-
a 1 eq { pop (Error: a can't be 1) false } if % ... error encountered: Replace "true" with "false (error message)"
1218
-
a 9 eq { pop (Error: a can't be 9) false } if
1219
-
b 5 gt { pop (Error: b must be 5 or less) false } if
1220
-
% ... More tests ...
1221
-
not { % Check status
1222
-
(An error occurred) ==
1223
-
== % Emit error message on stack
1224
-
stop % Do unwinding instead
1225
-
} if
1226
-
% If we get here, all is well and no boolean left on the stack
1101
+
a readonly pop % achieves nothing; a still writable
1102
+
/c a readonly def % c is readonly; a remains writable
1227
1103
```
1228
1104
1229
-
1230
-
When defining a procedure, string literals `(...)` are instantiated once (immediately) whereas array literals `[ ... ]` and dictionary literals `<< ... >>` are instantiated whenever the procedure is executed:
1231
-
1105
+
**String literals are shared across invocations** (arrays/dicts are not):
1232
1106
```postscript
1233
-
% Bad: Error prone
1234
1107
/proc {
1235
-
/a (0000) def % Safer to make a copy: /a (0000) 4 string copy def
proc % Subsequent runs: 1234 \n 1234 ; object was updated by first run
1242
-
...
1243
-
```
1244
-
1245
-
1246
-
Some PLRM terminology is a source of confusion. As a result of the following command:
1247
-
1248
-
```postscript
1249
-
/a [ 1 2 3 ] def
1250
-
/b a def
1111
+
proc % First run: a = "1234"
1112
+
proc % Subsequent: a starts as "1234", not "0000"!
1251
1113
```
1252
-
1253
-
-`a` is referred to as the "object" (within the `currentdict`)
1254
-
- The `--array--` created by `]` is referred to as "the storage for the object in VM" (either global or local VM depending on the allocation mode indicated by `currentglobal`)
1255
-
-`b` is also an "object" that refers to the same VM storage as `a`
1256
-
1257
-
The terminology differs from many languages where the array itself would be referred to as an object and `a` and `b` would be referred to as names or references.
0 commit comments