src/fccache.c | 2 +- src/fccfg.c | 4 ++-- src/fcdir.c | 6 +++--- src/fcint.h | 11 +++++++++++ src/fcstr.c | 47 +++++++++++++++++++++++++++++++++-------------- src/fcxml.c | 2 +- 6 files changed, 51 insertions(+), 21 deletions(-) New commits: commit d570a841a2aa9d770578aa149e43bb2e5bd0f2df Author: Patrick Haller <patrick.haller@xxxxxxxxxxxxxxxxx> Date: Sat Jan 9 03:06:31 2016 +0100 Optimizations in FcStrSet Applied optimizations: - skip duplicate check in FcStrSetAppend for values originating from readdir() - grow FcStrSet in 64-element bulks for local FcStrSets (FcConfig layout unaltered) Starting gedit is measured to Unoptimized Optimized user[s] 0,806 0,579 sys[s] 0,062 0,062 Total Instr Fetch Cost: 1.658.683.750 895.069.820 Cachegrind D Refs: 513.917.619 312.000.436 Cachegrind Dl Misses: 8.605.632 4.954.639 diff --git a/src/fccache.c b/src/fccache.c index f2b09cb..b681a5e 100644 --- a/src/fccache.c +++ b/src/fccache.c @@ -590,7 +590,7 @@ FcCacheTimeValid (FcConfig *config, FcCache *cache, struct stat *dir_stat) static FcBool FcCacheDirsValid (FcConfig *config, FcCache *cache) { - FcStrSet *dirs = FcStrSetCreate (); + FcStrSet *dirs = FcStrSetCreateEx (FCSS_GROW_BY_64); FcBool ret = FcFalse; const FcChar8 *sysroot = FcConfigGetSysRoot (config); FcChar8 *d; diff --git a/src/fccfg.c b/src/fccfg.c index 5f8f644..9f8ee7c 100644 --- a/src/fccfg.c +++ b/src/fccfg.c @@ -2205,7 +2205,7 @@ FcConfigAppFontAddFile (FcConfig *config, return FcFalse; } - subdirs = FcStrSetCreate (); + subdirs = FcStrSetCreateEx (FCSS_GROW_BY_64); if (!subdirs) return FcFalse; @@ -2252,7 +2252,7 @@ FcConfigAppFontAddDir (FcConfig *config, return FcFalse; } - dirs = FcStrSetCreate (); + dirs = FcStrSetCreateEx (FCSS_GROW_BY_64); if (!dirs) return FcFalse; diff --git a/src/fcdir.c b/src/fcdir.c index f4807dd..a046eae 100644 --- a/src/fcdir.c +++ b/src/fcdir.c @@ -248,7 +248,7 @@ FcDirScanConfig (FcFontSet *set, goto bail; } - files = FcStrSetCreate (); + files = FcStrSetCreateEx (FCSS_ALLOW_DUPLICATES | FCSS_GROW_BY_64); if (!files) { ret = FcFalse; @@ -349,7 +349,7 @@ FcDirCacheScan (const FcChar8 *dir, FcConfig *config) if (!set) goto bail; - dirs = FcStrSetCreate (); + dirs = FcStrSetCreateEx (FCSS_GROW_BY_64); if (!dirs) goto bail1; @@ -404,7 +404,7 @@ FcDirCacheRescan (const FcChar8 *dir, FcConfig *config) d = FcStrdup (dir); if (FcStatChecksum (d, &dir_stat) < 0) goto bail; - dirs = FcStrSetCreate (); + dirs = FcStrSetCreateEx (FCSS_GROW_BY_64); if (!dirs) goto bail; diff --git a/src/fcint.h b/src/fcint.h index 8fa01d6..ee6cc99 100644 --- a/src/fcint.h +++ b/src/fcint.h @@ -339,11 +339,19 @@ struct _FcCharSet { FcCharLeaf)) #define FcCharSetNumbers(c) FcOffsetMember(c,numbers_offset,FcChar16) +#define FCSS_DEFAULT 0 /* default behavior */ +#define FCSS_ALLOW_DUPLICATES 1 /* allows for duplicate strings in the set */ +#define FCSS_GROW_BY_64 2 /* grows buffer by 64 elements instead of 1 */ + +#define FcStrSetHasControlBit(s,c) (s->control & c) +#define FcStrSetHasControlBits(s,c) ( (c) == (s->control & (c)) ) + struct _FcStrSet { FcRef ref; /* reference count */ int num; int size; FcChar8 **strs; + unsigned int control; /* control bits for set behavior */ }; struct _FcStrList { @@ -1113,6 +1121,9 @@ FcPrivate FcBool FcIsFsMtimeBroken (const FcChar8 *dir); /* fcstr.c */ +FcPrivate FcStrSet * +FcStrSetCreateEx (unsigned int control); + FcPrivate FcBool FcStrSetAddLangs (FcStrSet *strs, const char *languages); diff --git a/src/fcstr.c b/src/fcstr.c index 29a577d..b65492d 100644 --- a/src/fcstr.c +++ b/src/fcstr.c @@ -880,7 +880,7 @@ FcStrBuildFilename (const FcChar8 *path, if (!path) return NULL; - sset = FcStrSetCreate (); + sset = FcStrSetCreateEx (FCSS_ALLOW_DUPLICATES | FCSS_GROW_BY_64); if (!sset) return NULL; @@ -1130,6 +1130,12 @@ FcStrCanonFilename (const FcChar8 *s) FcStrSet * FcStrSetCreate (void) { + return FcStrSetCreateEx (FCSS_DEFAULT); +} + +FcStrSet * +FcStrSetCreateEx (unsigned int control) +{ FcStrSet *set = malloc (sizeof (FcStrSet)); if (!set) return 0; @@ -1137,29 +1143,42 @@ FcStrSetCreate (void) set->num = 0; set->size = 0; set->strs = 0; + set->control = control; return set; } static FcBool +_FcStrSetGrow (FcStrSet *set, int growElements) +{ + /* accommodate an additional NULL entry at the end of the array */ + FcChar8 **strs = malloc ((set->size + growElements + 1) * sizeof (FcChar8 *)); + if (!strs) + return FcFalse; + if (set->num) + memcpy (strs, set->strs, set->num * sizeof (FcChar8 *)); + if (set->strs) + free (set->strs); + set->size = set->size + growElements; + set->strs = strs; + return FcTrue; +} + +static FcBool _FcStrSetAppend (FcStrSet *set, FcChar8 *s) { - if (FcStrSetMember (set, s)) + if (!FcStrSetHasControlBit (set, FCSS_ALLOW_DUPLICATES)) { - FcStrFree (s); - return FcTrue; + if (FcStrSetMember (set, s)) + { + FcStrFree (s); + return FcTrue; + } } if (set->num == set->size) { - FcChar8 **strs = malloc ((set->size + 2) * sizeof (FcChar8 *)); - - if (!strs) - return FcFalse; - if (set->num) - memcpy (strs, set->strs, set->num * sizeof (FcChar8 *)); - if (set->strs) - free (set->strs); - set->size = set->size + 1; - set->strs = strs; + int growElements = FcStrSetHasControlBit (set, FCSS_GROW_BY_64) ? 64 : 1; + if (!_FcStrSetGrow(set, growElements)) + return FcFalse; } set->strs[set->num++] = s; set->strs[set->num] = 0; diff --git a/src/fcxml.c b/src/fcxml.c index 52a0668..cd8fff1 100644 --- a/src/fcxml.c +++ b/src/fcxml.c @@ -3158,7 +3158,7 @@ FcConfigParseAndLoadDir (FcConfig *config, strcat ((char *) file, "/"); base = file + strlen ((char *) file); - files = FcStrSetCreate (); + files = FcStrSetCreateEx (FCSS_GROW_BY_64); if (!files) { ret = FcFalse; _______________________________________________ Fontconfig mailing list Fontconfig@xxxxxxxxxxxxxxxxxxxxx http://lists.freedesktop.org/mailman/listinfo/fontconfig