Character counts are a pretty terrible measure of anything, but it's
still the main measure of length used in most subtitling standards
(because subtitling standards are written under the assumption that the
tools are terrible (which is generally an accurate assumption)).
100 no-op non-amend commits on a subtitle file with 6689 dialogue lines,
with the undo limit set to 100:
Without flyweight:
No video open:
Initial memory usage: 30.6 MB
Final memory usage: 498.0 MB
Elapsed time: 6.3 seconds
Video open, using libass:
Initial memory usage: 54.3 MB
Final memory usage: 653.3 MB
Elapsed time: 23.7 seconds
With flyweight:
No video open:
Initial memory usage: 26.0 MB
Final memory usage: 104.5 MB
Elapsed time: 3.0 seconds
Video open, using libass:
Initial memory usage: 46.7 MB
Final memory usage: 251.8 MB
Elapsed time: 13.0 seconds
No video open:
Memory usage: -79%
Time: -52%
Video open:
Memory usage: -61.5%
Time: -45%
100 no-op amend commits on a line in the middle of a subtitle file with
6689 dialogue lines, with video open:
Without flyweight:
Initial memory usage: 48.2 MB
Final memory usage: 182.3 MB
Elapsed time: 22.3 seconds
With flyweight:
Initial memory usage: 39.8 MB
Final memory usage: 165.8 MB
Elapsed time: 13.8 seconds
Note: The large jump in memory usage here is due to that the benchmark
is blocking the main thread, so at the end there are ~100 video frames
waiting to be displayed.
This eliminates the need to explicitly delete the parsed blocks.
Also go ahead and remove AssDialogue::Blocks since it's really not a
very good idea in general.
FcFontRenderPrepare discards excess family names and fullnames, so in
some cases it may be impossible to verify that the font returned by it
is the one we asked for. To work around this, prefilter the available
fonts to only do fontconfig's matching on the ones with the correct
names.
Make two passes over the file to collect all of the styles before
processing the dialogue lines, as the styles section can legally come
after the dialogue lines which use those styles.
Dealing with multiple instances of each section makes the code
significantly more complicated, and in most cases Aegisub doesn't
actually bother to handle it correctly.