googlefonts / fontc

Where in we pursue oxidizing (context: https://github.com/googlefonts/oxidize) fontmake.
Apache License 2.0
66 stars 12 forks source link

Generating GPOS takes a long time #610

Open rsheeter opened 7 months ago

rsheeter commented 7 months ago

If I print the time for bytes_for in fontbe/src/font.rs GPOS takes ~10x GSUB which takes ~50x the next table in line:

$ cargo build --release && rm -rf build/ && time target/release/fontc ../googlesans/source/GoogleSans/GoogleSans.designspace
...
bytes_for Avar took 0.0ms
bytes_for Cmap took 0.1ms
bytes_for Fvar took 0.0ms
bytes_for Head took 0.0ms
bytes_for Hhea took 0.0ms
bytes_for Hmtx took 0.0ms
bytes_for Glyf took 0.3ms
bytes_for Gvar took 0.6ms
bytes_for Loca took 0.0ms
bytes_for Maxp took 0.0ms
bytes_for Name took 0.1ms
bytes_for Os2 took 0.0ms
bytes_for Post took 1.7ms
bytes_for Stat took 0.0ms
bytes_for Hvar took 0.1ms
bytes_for Gpos took 1025.9ms
bytes_for Gsub took 85.5ms
bytes_for Gdef took 0.3ms

real    0m6.334s

GPOS is about 16% of the total build time (real). We know we generate over-large GPOS tables (https://github.com/googlefonts/fontc/issues/593), that probably doesn't help.

https://github.com/googlefonts/fontc/pull/611 is my exploration that led to discovering this; I had assumed if I did everything except layout ahead it would help but it made no real difference which led me to the surprising bytes_for breakdown.

belluzj commented 7 months ago

Random thought (I've told @anthrotype on the side I think): you may benefit from translating to Rust the GPOS compaction from here: https://github.com/fonttools/fonttools/pull/2326. It's not super slow even though it's Python, so it might be fast enough in Rust, and it doesn't need to know about the glyph's Unicode properties (so no need for GSUB closure) in order to decide how to split the subtables, it does so only by looking at the filled-in/empty areas of the matrices. Let me know if you have any questions.

anthrotype commented 7 months ago

thanks Jany, that's worth looking into. I think it probably deserves its own issue https://github.com/googlefonts/fontc/issues/612

rsheeter commented 7 months ago

Kerning is the majority of the critical path when I build GS locally. Hopefully we can speed it up and/or parallelize it!

image

cmyr commented 7 months ago

why is kerning there twice?

rsheeter commented 7 months ago

The first is FE the second is BE. Apparently I didn't see the need to distinguish them very much :D