fontconfig initialization spends most of its time parsing XML configuration files in /etc/fonts/conf.d/

Bug #1590804 reported by Florian Boucault
12
This bug affects 2 people
Affects Status Importance Assigned to Milestone
Canonical System Image
In Progress
Low
kevin gunn
fontconfig (Ubuntu)
Confirmed
Medium
Unassigned
qtbase-opensource-src (Ubuntu)
Invalid
Undecided
Alberto Aguirre

Bug Description

While profiling the startup of QML apps on the BQ E4.5 phone (armhf) I noticed that a significant amount of time (around 35ms) was spent solely on parsing the XML configuration files in /etc/fonts/conf.d/
There seems to be around 40 files on Ubuntu Phone in that directory.

Tags: performance
tags: added: performance
Bill Filler (bfiller)
Changed in canonical-devices-system-image:
assignee: nobody → kevin gunn (kgunn72)
milestone: none → backlog
importance: Undecided → High
Revision history for this message
Florian Boucault (fboucault) wrote :
Download full text (3.5 KiB)

For information, output of strace related to that:

open("/etc/fonts/conf.d/10-antialias.conf", O_RDONLY|O_LARGEFILE|O_CLOEXEC) = 25
open("/etc/fonts/conf.d/10-hinting-slight.conf", O_RDONLY|O_LARGEFILE|O_CLOEXEC) = 25
open("/etc/fonts/conf.d/10-hinting.conf", O_RDONLY|O_LARGEFILE|O_CLOEXEC) = 25
open("/etc/fonts/conf.d/10-scale-bitmap-fonts.conf", O_RDONLY|O_LARGEFILE|O_CLOEXEC) = 25
open("/etc/fonts/conf.d/11-lcdfilter-default.conf", O_RDONLY|O_LARGEFILE|O_CLOEXEC) = 25
open("/etc/fonts/conf.d/20-unhint-small-dejavu-lgc-sans-mono.conf", O_RDONLY|O_LARGEFILE|O_CLOEXEC) = 25
open("/etc/fonts/conf.d/20-unhint-small-dejavu-lgc-sans.conf", O_RDONLY|O_LARGEFILE|O_CLOEXEC) = 25
open("/etc/fonts/conf.d/20-unhint-small-dejavu-lgc-serif.conf", O_RDONLY|O_LARGEFILE|O_CLOEXEC) = 25
open("/etc/fonts/conf.d/20-unhint-small-dejavu-sans-mono.conf", O_RDONLY|O_LARGEFILE|O_CLOEXEC) = 25
open("/etc/fonts/conf.d/20-unhint-small-dejavu-sans.conf", O_RDONLY|O_LARGEFILE|O_CLOEXEC) = 25
open("/etc/fonts/conf.d/20-unhint-small-dejavu-serif.conf", O_RDONLY|O_LARGEFILE|O_CLOEXEC) = 25
open("/etc/fonts/conf.d/20-unhint-small-vera.conf", O_RDONLY|O_LARGEFILE|O_CLOEXEC) = 25
open("/etc/fonts/conf.d/30-metric-aliases.conf", O_RDONLY|O_LARGEFILE|O_CLOEXEC) = 25
open("/etc/fonts/conf.d/30-urw-aliases.conf", O_RDONLY|O_LARGEFILE|O_CLOEXEC) = 25
open("/etc/fonts/conf.d/40-nonlatin.conf", O_RDONLY|O_LARGEFILE|O_CLOEXEC) = 25
open("/etc/fonts/conf.d/45-latin.conf", O_RDONLY|O_LARGEFILE|O_CLOEXEC) = 25
open("/etc/fonts/conf.d/49-sansserif.conf", O_RDONLY|O_LARGEFILE|O_CLOEXEC) = 25
open("/etc/fonts/conf.d/50-user.conf", O_RDONLY|O_LARGEFILE|O_CLOEXEC) = 25
open("/etc/fonts/conf.d/51-local.conf", O_RDONLY|O_LARGEFILE|O_CLOEXEC) = 25
open("/etc/fonts/local.conf", O_RDONLY|O_LARGEFILE|O_CLOEXEC) = 26
open("/etc/fonts/conf.d/57-dejavu-sans-mono.conf", O_RDONLY|O_LARGEFILE|O_CLOEXEC) = 25
open("/etc/fonts/conf.d/57-dejavu-sans.conf", O_RDONLY|O_LARGEFILE|O_CLOEXEC) = 25
open("/etc/fonts/conf.d/57-dejavu-serif.conf", O_RDONLY|O_LARGEFILE|O_CLOEXEC) = 25
open("/etc/fonts/conf.d/58-dejavu-lgc-sans-mono.conf", O_RDONLY|O_LARGEFILE|O_CLOEXEC) = 25
open("/etc/fonts/conf.d/58-dejavu-lgc-sans.conf", O_RDONLY|O_LARGEFILE|O_CLOEXEC) = 25
open("/etc/fonts/conf.d/58-dejavu-lgc-serif.conf", O_RDONLY|O_LARGEFILE|O_CLOEXEC) = 25
open("/etc/fonts/conf.d/60-latin.conf", O_RDONLY|O_LARGEFILE|O_CLOEXEC) = 25
open("/etc/fonts/conf.d/64-01-tlwg-kinnari.conf", O_RDONLY|O_LARGEFILE|O_CLOEXEC) = 25
open("/etc/fonts/conf.d/65-droid-sans-fallback.conf", O_RDONLY|O_LARGEFILE|O_CLOEXEC) = 25
open("/etc/fonts/conf.d/65-fonts-persian.conf", O_RDONLY|O_LARGEFILE|O_CLOEXEC) = 25
open("/etc/fonts/conf.d/65-fonts-takao-pgothic.conf", O_RDONLY|O_LARGEFILE|O_CLOEXEC) = 25
open("/etc/fonts/conf.d/65-nonlatin.conf", O_RDONLY|O_LARGEFILE|O_CLOEXEC) = 25
open("/etc/fonts/conf.d/65-wqy-microhei.conf", O_RDONLY|O_LARGEFILE|O_CLOEXEC) = 25
open("/etc/fonts/conf.d/66-lohit-devanagari.conf", O_RDONLY|O_LARGEFILE|O_CLOEXEC) = 25
open("/etc/fonts/conf.d/66-lohit-punjabi.conf", O_RDONLY|O_LARGEFILE|O_CLOEXEC) = 25
open("/etc/fonts/conf.d/69-unifont.conf", O_RDONLY|O_LARGEFILE|O_CLOEXEC) = 25
open("/etc/fonts/conf.d/70-no-bitmaps....

Read more...

Revision history for this message
Gunnar Hjalmarsson (gunnarhj) wrote :

Hmm.. fontconfig must parse those XML files at startup to do its job. While you indicate that it happens at startup of QML apps, my belief was that it happens already at login.

It may well be possible to reduce the number of fontconfig config files, but that would be a large project, where you'd need to make sure fore every single language that the rendering isn't changed adversely. AFAIK, the fontconfig and fonts-* packages currently used in Ubuntu touch are the same as on the desktop.

Revision history for this message
Florian Boucault (fboucault) wrote :

The output of strace shows that fontconfig opens those file during every QML application startup.

A solution to this would be to introduce a caching system: after fontconfig opens and parses those files the first time it could serialize the result to disk for subsequent starts.

Revision history for this message
Jean-Baptiste Lallement (jibel) wrote :

For a given user only a subset of these fonts are used, so this could probably be mitigated by installing fonts on demand with the language (reported in bug 1577369)

Revision history for this message
Gunnar Hjalmarsson (gunnarhj) wrote :

On 2016-06-14 20:41, Florian Boucault wrote:
> The output of strace shows that fontconfig opens those file during
> every QML application startup.
>
> A solution to this would be to introduce a caching system: after
> fontconfig opens and parses those files the first time it could
> serialize the result to disk for subsequent starts.

From "man fc-cache":

<quote>
fc-cache scans the font directories on the system and builds font information cache files for applications using fontconfig for their font handling.

If directory arguments are not given, fc-cache uses each directory in the current font configuration. Each directory is scanned for font files readable by FreeType. A cache is created which contains properties of each font and the associated filename. This cache is used to speed up application startup when using the fontconfig library.
</quote>

Maybe there is a simple solution available.

Revision history for this message
Alberto Aguirre (albaguirre) wrote :

I tried fc-cache, but starting a qml app still continues to open up the conf files.

Digging through Qt source to understand where these calls are coming from.

Revision history for this message
Alberto Aguirre (albaguirre) wrote :

From the attached backtrace, It seems that Qt calls FcInitReinitialize when populating its font database (a QGenericUnixFontDatabase instance provided by Qtubuntu) - that explains why re-parses the conf files everytime.

See http://code.qt.io/cgit/qt/qtbase.git/tree/src/platformsupport/fontdatabases/fontconfig/qfontconfigdatabase.cpp?h=v5.4.1#n439

Changed in canonical-devices-system-image:
status: New → In Progress
milestone: backlog → 13
Changed in qtbase-opensource-src (Ubuntu):
assignee: nobody → Alberto Aguirre (albaguirre)
Revision history for this message
Alberto Aguirre (albaguirre) wrote :

So actually, fontconfig does not cache conf files at all... it caches fonts but not conf files...

fontconfg needs support to also cache the result of the parsing of the xml config file parsing. It seems a low priority effort for less than a 35ms improvement in startup.

Revision history for this message
Alberto Aguirre (albaguirre) wrote :

Also FcInitReinitialize and FcInitBringUptoDate both will do the same thing the first time is called in the process, so wouldn't help for startup either.

Changed in qtbase-opensource-src (Ubuntu):
status: New → Invalid
Revision history for this message
Launchpad Janitor (janitor) wrote :

Status changed to 'Confirmed' because the bug affects multiple users.

Changed in fontconfig (Ubuntu):
status: New → Confirmed
Changed in canonical-devices-system-image:
importance: High → Low
Changed in canonical-devices-system-image:
milestone: 13 → backlog
Changed in fontconfig (Ubuntu):
importance: Undecided → Medium
To post a comment you must log in.
This report contains Public information  
Everyone can see this information.

Other bug subscribers

Remote bug watches

Bug watches keep track of this bug in other bug trackers.