Summary: | Performance regression in git compared 2.11 | ||
---|---|---|---|
Product: | fontconfig | Reporter: | Antonio Orefice <kokoko3k> |
Component: | library | Assignee: | Akira TAGOH <akira> |
Status: | RESOLVED FIXED | QA Contact: | Behdad Esfahbod <freedesktop> |
Severity: | normal | ||
Priority: | medium | CC: | akira, ebiggers3, fontconfig-bugs, fontconfigbugs |
Version: | unspecified | ||
Hardware: | Other | ||
OS: | All | ||
Whiteboard: | |||
i915 platform: | i915 features: | ||
Attachments: |
grep ^stat64 /tmp/out_fast|grep font >/tmp/stat_fast.txt
grep ^stat64 /tmp/out_slow|grep font >/tmp/stat_slow.txt complete strace fast complete strace slow |
Description
Antonio Orefice
2016-03-07 16:04:25 UTC
Created attachment 122140 [details]
grep ^stat64 /tmp/out_slow|grep font >/tmp/stat_slow.txt
Created attachment 122141 [details]
complete strace fast
Created attachment 122142 [details]
complete strace slow
By simply overriding the fontconfig shared library, the issue goes away. The following is with fontconfig-ultimate installed, and i'm going to preload the standard arch fontconfig: LD_PRELOAD=/tmp/usr/lib/libfontconfig.so /tmp/startuptime.sh /tmp/startuptime.sh: riga 3: 7602 Terminato /tmp/mysleep 999 real 0m0.376s user 0m0.000s sys 0m0.003s On a much more powerfull i5 cpu, the difference is still there; i've about 0.1seconds difference in favour of vanilla fontconfig. Same problem here. A git bisect shows this as the offending commit: https://cgit.freedesktop.org/fontconfig/commit/?id=f44bfad235e63bb792c38e16ae1fbd281ec1453b To be more precise, the commit mentioned above adds a call to FcDirScanOnly() which causes all the stat() calls Antonio has seen. FcDirScanOnly() will *always* be called, even if the cache turns out to be perfectly valid. To give you some more numbers, a "time fc-list" in a terminal went from ~30ms with fontconfig 2.11.1 to ~200ms with fontconfig 2.11.94. As a result, seemingly "simple" applications like dmenu show a noticeable lag on startup. I'm on an i7-3770 with 32GB RAM, so neither CPU speed nor the size of IO cache should be an issue here. I'm not familiar with fontconfig's code, but I noticed that FcCacheDirsValid() gets called 18 times. Is that neccessary? I added some ugly static variables to make fontconfig "cache" the first return value of FcCacheDirsValid() and I'm back at my ~30ms. Thus, *one* call to FcDirScanOnly() is just fine. I have been encountering this bug after upgrading from fontconfig 2.11.1-2 to fontconfig 2.11.94-1 yesterday. I can confirm the previous post that places the blame on the following commit: commit f44bfad235e63bb792c38e16ae1fbd281ec1453b Author: Akira TAGOH <akira@tagoh.org> Date: Thu Jun 5 19:06:02 2014 +0900 Workaround another race condition issue See https://bugzilla.redhat.com/show_bug.cgi?id=921706 Also, the main reason for the performance regression is not the stat() calls per se, but rather the inefficient "string sets" which take n^2 time to build, causing millions of string comparisons to occur when any application is started. See FcStrSetMember(), called by _FcStrSetAppend(). Still, the entire "directory scan" seems unnecessary to me. I don't yet fully understand what problem this change was meant to solve, but in my opinion it's not acceptable to iterate through all font files. The purpose of the fontconfig cache is to make that unnecessary, is it not? I don't know how much or even if it is relevant, but some further tests show that uninstalling xorg fonts makes things fast again: https://bbs.archlinux.org/viewtopic.php?id=209687 Please ignore the previous one, it is just that there are a lot of items in the arch xorg-fonts packages; thus the slowness. This is also encountered by @xiaqqiax (telegram-bridged) on #archlinux-cn@freenode.net. He was using 2.11.94, and got some 1-minute startup time due to his bad habit of putting fontforge SFDirs (one file per glyph!) in ~/.fonts (which didn't trigger anything that bad in 2.11.1). Confirming Arthur Wang's report here. Noob here. I have noticed that there is an inefficiency in the function: FcCacheDirsValid (That was newly added). The only value that it is really using is "FcCache::dirs_count" so the whole stuff around "FcStrSet" is totally rubbish. One could simply rewrite the "FcDirScanOnly" function so that it only counts the directories (dirs_count) without all that stringset stuff. https://gist.github.com/anonymous/5117f5ac08ae50f38e12ddebd1fb2e41 (Had a hard time writing that code, my C is a little rusty...) Note: The patch compiles but I haven't tried it yet. should be better in the latest git. please test. atm it doesn't build for me: make[1]: Entering directory '/tmp/fontconfig/doc' make[1]: '.gitignore' is up to date. make[1]: Leaving directory '/tmp/fontconfig/doc' make all-recursive make[1]: Entering directory '/tmp/fontconfig' Making all in fontconfig make[2]: Entering directory '/tmp/fontconfig/fontconfig' make[2]: Leaving directory '/tmp/fontconfig/fontconfig' Making all in fc-blanks make[2]: Entering directory '/tmp/fontconfig/fc-blanks' GEN fcblanks.h File "./fc-blanks.py", line 50 raise RuntimeError, "Unexpected escape code" ^ SyntaxError: invalid syntax Makefile:592: recipe for target 'fcblanks.h' failed make[2]: *** [fcblanks.h] Error 1 make[2]: Leaving directory '/tmp/fontconfig/fc-blanks' Makefile:578: recipe for target 'all-recursive' failed make[1]: *** [all-recursive] Error 1 make[1]: Leaving directory '/tmp/fontconfig' Makefile:462: recipe for target 'all' failed make: *** [all] Error 2 @Akira TAGOH: Yes, git is fine again. Thank you! :) (In reply to Antonio Orefice from comment #14) > make[2]: Entering directory '/tmp/fontconfig/fc-blanks' > GEN fcblanks.h > File "./fc-blanks.py", line 50 > raise RuntimeError, "Unexpected escape code" > ^ > SyntaxError: invalid syntax Fixed in git. should works now. I upgraded to version 2.11.95 and the performance regression appears to be fixed. |
Use of freedesktop.org services, including Bugzilla, is subject to our Code of Conduct. How we collect and use information is described in our Privacy Policy.