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:
parent
98434b3392
commit
d570a841a2
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
11
src/fcint.h
11
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);
|
||||
|
||||
|
|
47
src/fcstr.c
47
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;
|
||||
|
||||
|
@ -1129,6 +1129,12 @@ FcStrCanonFilename (const FcChar8 *s)
|
|||
|
||||
FcStrSet *
|
||||
FcStrSetCreate (void)
|
||||
{
|
||||
return FcStrSetCreateEx (FCSS_DEFAULT);
|
||||
}
|
||||
|
||||
FcStrSet *
|
||||
FcStrSetCreateEx (unsigned int control)
|
||||
{
|
||||
FcStrSet *set = malloc (sizeof (FcStrSet));
|
||||
if (!set)
|
||||
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Reference in New Issue