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
This commit is contained in:
Patrick Haller 2016-01-09 03:06:31 +01:00 committed by Akira TAGOH
parent 98434b3392
commit d570a841a2
6 changed files with 51 additions and 21 deletions

View File

@ -590,7 +590,7 @@ FcCacheTimeValid (FcConfig *config, FcCache *cache, struct stat *dir_stat)
static FcBool static FcBool
FcCacheDirsValid (FcConfig *config, FcCache *cache) FcCacheDirsValid (FcConfig *config, FcCache *cache)
{ {
FcStrSet *dirs = FcStrSetCreate (); FcStrSet *dirs = FcStrSetCreateEx (FCSS_GROW_BY_64);
FcBool ret = FcFalse; FcBool ret = FcFalse;
const FcChar8 *sysroot = FcConfigGetSysRoot (config); const FcChar8 *sysroot = FcConfigGetSysRoot (config);
FcChar8 *d; FcChar8 *d;

View File

@ -2205,7 +2205,7 @@ FcConfigAppFontAddFile (FcConfig *config,
return FcFalse; return FcFalse;
} }
subdirs = FcStrSetCreate (); subdirs = FcStrSetCreateEx (FCSS_GROW_BY_64);
if (!subdirs) if (!subdirs)
return FcFalse; return FcFalse;
@ -2252,7 +2252,7 @@ FcConfigAppFontAddDir (FcConfig *config,
return FcFalse; return FcFalse;
} }
dirs = FcStrSetCreate (); dirs = FcStrSetCreateEx (FCSS_GROW_BY_64);
if (!dirs) if (!dirs)
return FcFalse; return FcFalse;

View File

@ -248,7 +248,7 @@ FcDirScanConfig (FcFontSet *set,
goto bail; goto bail;
} }
files = FcStrSetCreate (); files = FcStrSetCreateEx (FCSS_ALLOW_DUPLICATES | FCSS_GROW_BY_64);
if (!files) if (!files)
{ {
ret = FcFalse; ret = FcFalse;
@ -349,7 +349,7 @@ FcDirCacheScan (const FcChar8 *dir, FcConfig *config)
if (!set) if (!set)
goto bail; goto bail;
dirs = FcStrSetCreate (); dirs = FcStrSetCreateEx (FCSS_GROW_BY_64);
if (!dirs) if (!dirs)
goto bail1; goto bail1;
@ -404,7 +404,7 @@ FcDirCacheRescan (const FcChar8 *dir, FcConfig *config)
d = FcStrdup (dir); d = FcStrdup (dir);
if (FcStatChecksum (d, &dir_stat) < 0) if (FcStatChecksum (d, &dir_stat) < 0)
goto bail; goto bail;
dirs = FcStrSetCreate (); dirs = FcStrSetCreateEx (FCSS_GROW_BY_64);
if (!dirs) if (!dirs)
goto bail; goto bail;

View File

@ -339,11 +339,19 @@ struct _FcCharSet {
FcCharLeaf)) FcCharLeaf))
#define FcCharSetNumbers(c) FcOffsetMember(c,numbers_offset,FcChar16) #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 { struct _FcStrSet {
FcRef ref; /* reference count */ FcRef ref; /* reference count */
int num; int num;
int size; int size;
FcChar8 **strs; FcChar8 **strs;
unsigned int control; /* control bits for set behavior */
}; };
struct _FcStrList { struct _FcStrList {
@ -1113,6 +1121,9 @@ FcPrivate FcBool
FcIsFsMtimeBroken (const FcChar8 *dir); FcIsFsMtimeBroken (const FcChar8 *dir);
/* fcstr.c */ /* fcstr.c */
FcPrivate FcStrSet *
FcStrSetCreateEx (unsigned int control);
FcPrivate FcBool FcPrivate FcBool
FcStrSetAddLangs (FcStrSet *strs, const char *languages); FcStrSetAddLangs (FcStrSet *strs, const char *languages);

View File

@ -880,7 +880,7 @@ FcStrBuildFilename (const FcChar8 *path,
if (!path) if (!path)
return NULL; return NULL;
sset = FcStrSetCreate (); sset = FcStrSetCreateEx (FCSS_ALLOW_DUPLICATES | FCSS_GROW_BY_64);
if (!sset) if (!sset)
return NULL; return NULL;
@ -1129,6 +1129,12 @@ FcStrCanonFilename (const FcChar8 *s)
FcStrSet * FcStrSet *
FcStrSetCreate (void) FcStrSetCreate (void)
{
return FcStrSetCreateEx (FCSS_DEFAULT);
}
FcStrSet *
FcStrSetCreateEx (unsigned int control)
{ {
FcStrSet *set = malloc (sizeof (FcStrSet)); FcStrSet *set = malloc (sizeof (FcStrSet));
if (!set) if (!set)
@ -1137,29 +1143,42 @@ FcStrSetCreate (void)
set->num = 0; set->num = 0;
set->size = 0; set->size = 0;
set->strs = 0; set->strs = 0;
set->control = control;
return set; return set;
} }
static FcBool static FcBool
_FcStrSetAppend (FcStrSet *set, FcChar8 *s) _FcStrSetGrow (FcStrSet *set, int growElements)
{ {
if (FcStrSetMember (set, s)) /* accommodate an additional NULL entry at the end of the array */
{ FcChar8 **strs = malloc ((set->size + growElements + 1) * sizeof (FcChar8 *));
FcStrFree (s);
return FcTrue;
}
if (set->num == set->size)
{
FcChar8 **strs = malloc ((set->size + 2) * sizeof (FcChar8 *));
if (!strs) if (!strs)
return FcFalse; return FcFalse;
if (set->num) if (set->num)
memcpy (strs, set->strs, set->num * sizeof (FcChar8 *)); memcpy (strs, set->strs, set->num * sizeof (FcChar8 *));
if (set->strs) if (set->strs)
free (set->strs); free (set->strs);
set->size = set->size + 1; set->size = set->size + growElements;
set->strs = strs; set->strs = strs;
return FcTrue;
}
static FcBool
_FcStrSetAppend (FcStrSet *set, FcChar8 *s)
{
if (!FcStrSetHasControlBit (set, FCSS_ALLOW_DUPLICATES))
{
if (FcStrSetMember (set, s))
{
FcStrFree (s);
return FcTrue;
}
}
if (set->num == set->size)
{
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++] = s;
set->strs[set->num] = 0; set->strs[set->num] = 0;

View File

@ -3158,7 +3158,7 @@ FcConfigParseAndLoadDir (FcConfig *config,
strcat ((char *) file, "/"); strcat ((char *) file, "/");
base = file + strlen ((char *) file); base = file + strlen ((char *) file);
files = FcStrSetCreate (); files = FcStrSetCreateEx (FCSS_GROW_BY_64);
if (!files) if (!files)
{ {
ret = FcFalse; ret = FcFalse;