| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
Keep rendered source references in a dictionary instead of repeatedly scanning a list. Preserve first-reference order, formatting and duplicate removal. Add tests for line numbers, duplicate references, Unicode filenames and fallback order when sorting fails.
| Back | FazBrowse Home | New Git URL |
When writing a PO file, generate_po checks each source reference against a list of references it has already seen. If a message is used in lots of places, it keeps scanning a longer and longer list.
This uses a dictionary instead. It still keeps the first occurrence of each formatted reference, in the same order. The sorting, filename formatting and line-number option stay the same.
For a message with r different references, the duplicate-checking part goes from O(r²) to expected O(r). The sorting work is unchanged, so this doesn't make the whole writer linear.
I added tests for duplicate references, ordering, empty locations, missing and zero line numbers, Unicode filenames, filenames with spaces, and the existing fallback when locations can't be sorted. The tests also check that the input locations aren't changed.
Checks
Benchmarks
This helps most in the generated cases where messages have lots of source references. The largest measured gain was 4.28×, but that isn't a general speedup.
The real-project catalogs I tried didn't show a useful gain. The Odoo template was 1.036× slower without line numbers and 1.075× slower with them. The Django and Wagtail files have no source references, so they are controls, not examples of this lookup getting faster. Some small cases were slower too. I've kept all of them in the table.
Peak Python allocations were up to 1.088× higher in these cases. This is extra allocation during a write, not total process RAM.
Measured on Windows 11 with Python 3.15.0, using the median of eight timing runs and eight separate memory runs per version. The timer covers the complete write_po call, including sorting, formatting, encoding and writing to a fresh BytesIO. Setup and output checks are outside the timer.
There is one process, limited to two physical cores at a time, with rotating pairs. Both versions use the same pair for each repeat, and their order alternates. The 112 cases include 100 generated examples, two empty controls, eight public-catalog cases and two with location output turned off. The generated examples aren't collected production workloads, and small timing differences may be noise.
Runner and rerun steps · Benchmark script · All raw samples
The benchmark files are in a separate branch, not in this PR's code diff.
Show all 112 benchmark casesPublic catalog sources: