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
|
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;
|
||||||
|
|
|
@ -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;
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
|
|
||||||
|
|
11
src/fcint.h
11
src/fcint.h
|
@ -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);
|
||||||
|
|
||||||
|
|
47
src/fcstr.c
47
src/fcstr.c
|
@ -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
|
||||||
|
_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
|
static FcBool
|
||||||
_FcStrSetAppend (FcStrSet *set, FcChar8 *s)
|
_FcStrSetAppend (FcStrSet *set, FcChar8 *s)
|
||||||
{
|
{
|
||||||
if (FcStrSetMember (set, s))
|
if (!FcStrSetHasControlBit (set, FCSS_ALLOW_DUPLICATES))
|
||||||
{
|
{
|
||||||
FcStrFree (s);
|
if (FcStrSetMember (set, s))
|
||||||
return FcTrue;
|
{
|
||||||
|
FcStrFree (s);
|
||||||
|
return FcTrue;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (set->num == set->size)
|
if (set->num == set->size)
|
||||||
{
|
{
|
||||||
FcChar8 **strs = malloc ((set->size + 2) * sizeof (FcChar8 *));
|
int growElements = FcStrSetHasControlBit (set, FCSS_GROW_BY_64) ? 64 : 1;
|
||||||
|
if (!_FcStrSetGrow(set, growElements))
|
||||||
if (!strs)
|
return FcFalse;
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
set->strs[set->num++] = s;
|
set->strs[set->num++] = s;
|
||||||
set->strs[set->num] = 0;
|
set->strs[set->num] = 0;
|
||||||
|
|
|
@ -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;
|
||||||
|
|
Loading…
Reference in New Issue