Skip to content

Commit 283e78b

Browse files
committed
Reduce DEVELOPERS.md
1 parent 62d9cf4 commit 283e78b

1 file changed

Lines changed: 22 additions & 166 deletions

File tree

DEVELOPERS.md

Lines changed: 22 additions & 166 deletions
Original file line numberDiff line numberDiff line change
@@ -813,28 +813,9 @@ To configure a hook procedure for the named hooks in just a single encoder,
813813
create a hooks entries named like `qrcode.before`.
814814

815815

816-
### Profiling Results (including failed optimisation attempts)
816+
### Profiling Results
817817

818-
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.
838819

839820

840821
## Testing
@@ -1095,163 +1076,38 @@ Both scripts require `build/monolithic/barcode.ps` (run `make` first).
10951076

10961077
## Release Process
10971078

1098-
1. Update CHANGES date:
1099-
```bash
1100-
sed -i '1s/XXXX-XX-XX/YYYY-MM-DD/' CHANGES
1101-
git add CHANGES
1102-
git commit -m "Update CHANGES"
1103-
```
1104-
1105-
2. Review CHANGES for new/modified symbologies or options. Verify corresponding
1106-
updates exist in wikidocs:
1107-
- `wikidocs/symbologies/<Symbology-Name>.md`
1108-
- `wikidocs/options/<Option-Name>.md`
1109-
- `wikidocs/symbologies/Symbologies-Reference.md`
1110-
- `wikidocs/options/Options-Reference.md`
1111-
1112-
3. Ensure wikidocs submodule is up to date:
1113-
```bash
1114-
git -C wikidocs pull origin master
1115-
git add wikidocs
1116-
git commit -m "Bump wikidocs" # Skip if no changes
1117-
```
1118-
1119-
4. Push commits:
1120-
```bash
1121-
git push origin master
1122-
```
1123-
1124-
5. Wait for CI to pass:
1125-
```bash
1126-
gh run watch
1127-
```
1128-
1129-
6. Only after CI succeeds, create and push the tag:
1130-
```bash
1131-
make tag
1132-
git push origin YYYY-MM-DD
1133-
```
1134-
1135-
7. Watch the release workflow triggered by the tag:
1136-
```bash
1137-
gh run watch
1138-
```
1139-
1140-
8. Verify the release was created:
1141-
```bash
1142-
gh release view YYYY-MM-DD
1143-
```
1144-
1145-
9. Add placeholder for next release:
1146-
```bash
1147-
sed -i '1i XXXX-XX-XX\n\n*\n\n' CHANGES
1148-
git add CHANGES
1149-
git commit -m "Update CHANGES"
1150-
git push origin master
1151-
```
1152-
1153-
1154-
## PostScript Language paradigms
1155-
1156-
Pay attention to the direction of `roll`:
1157-
1158-
```postscript
1159-
(a) (b) (c) 3 1 roll => (c) (a) (b)
1160-
(a) (b) (c) 3 -1 roll => (b) (c) (a)
1161-
```
1162-
1163-
Understand the offset used by `index`:
1164-
1165-
```postscript
1166-
(a) (b) (c) 1 index => (a) (b) (c) (b)
1167-
```
1168-
1169-
Inserting stack elements requires `index` adjustment:
1170-
1171-
```postscript
1172-
(a) (b) (c) /x 1 index def => (a) (b) (c) ; and x = (c), not (b) due to /x on the stack!
1173-
```
1174-
1175-
GhostScript can recursively expand structures with `===`:
1176-
1177-
```postscript
1178-
[ [ << /a 1 >> << /b 2 >> ] [ << /c 3 >> ] /d ] ===
1179-
```
1180-
1181-
Dictionaries will dynamically grow as needed:
1079+
1. Update CHANGES date: `sed -i '1s/XXXX-XX-XX/YYYY-MM-DD/' CHANGES` and commit
1080+
2. Review CHANGES; verify wikidocs has corresponding symbology/option pages
1081+
3. Update wikidocs submodule if needed: `git -C wikidocs pull origin master`
1082+
4. Push commits, wait for CI: `gh run watch`
1083+
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
11821086

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-
```
11971087

1088+
## PostScript Language Reminders
11981089

1199-
Names and strings are treated as equivalent when compared:
1200-
1090+
**Stack operations:**
12011091
```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!
12031096
```
12041097

1205-
Understand that `readonly` does not affect its argument:
1206-
1098+
**`readonly` returns a new reference:**
12071099
```postscript
12081100
/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
12271103
```
12281104

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):
12321106
```postscript
1233-
% Bad: Error prone
12341107
/proc {
1235-
/a (0000) def % Safer to make a copy: /a (0000) 4 string copy def
1236-
a ==
1108+
/a (0000) def % Safer: /a (0000) 4 string copy def
12371109
a 0 (1234) putinterval
1238-
a ==
12391110
} def
1240-
proc % First run: 0000 \n 1234
1241-
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"!
12511113
```
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

Comments
 (0)