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
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;

View File

@ -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;

View File

@ -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;

View File

@ -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);

View File

@ -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;

View File

@ -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;