Hi,
I was looking at performance of FireFox3 startup using callgrind and
found a lot of calls to realloc() from FcCharSetPutLeaf(). During the
startup there are 10 calls to FcFontSort() that lead to 105242 calls to
FcCharSetPutLeaf() and 209842 calls to realloc(). I tried to
allocate/reallocate memory in bigger blocks and calls to realloc() were
reduced to 25982 when block size was 8 (patch is attached). Of course
some memory is wasted with this approach but number of instructions
needed to do FcFontSort() decreased from 176569552 to 125762052. Is it
possible to have similar optimalization in next releases of fontconfig?
Michal
diff --git a/src/fccharset.c b/src/fccharset.c
index 5da1312..027cab1 100644
--- a/src/fccharset.c
+++ b/src/fccharset.c
@@ -130,46 +130,54 @@ FcCharSetPutLeaf (FcCharSet *fcs,
{
intptr_t *leaves = FcCharSetLeaves (fcs);
FcChar16 *numbers = FcCharSetNumbers (fcs);
+ int capacity;
ucs4 >>= 8;
if (ucs4 >= 0x10000)
return FcFalse;
- if (!fcs->num)
- leaves = malloc (sizeof (*leaves));
- else
+
+ capacity = (((fcs->num) >> 3) << 3);
+ if ((fcs->num) % 8)
+ capacity += 8;
+
+ if (( fcs->num + 1) > capacity )
{
- intptr_t *new_leaves = realloc (leaves, (fcs->num + 1) *
- sizeof (*leaves));
- intptr_t distance = (intptr_t) new_leaves - (intptr_t) leaves;
-
- if (new_leaves && distance)
+ if (! fcs->num)
+ leaves = malloc ((capacity + 8) * sizeof (*leaves));
+ else
{
- int i;
+ intptr_t *new_leaves = realloc (leaves, (capacity + 8) *
+ sizeof (*leaves));
+ intptr_t distance = (intptr_t) new_leaves - (intptr_t) leaves;
+
+ if (new_leaves && distance)
+ {
+ int i;
- for (i = 0; i < fcs->num; i++)
- new_leaves[i] -= distance;
+ for (i = 0; i < fcs->num; i++)
+ new_leaves[i] -= distance;
+ }
+ leaves = new_leaves;
}
- leaves = new_leaves;
- }
- if (!leaves)
- return FcFalse;
-
- if (fcs->num)
- FcMemFree (FC_MEM_CHARSET, fcs->num * sizeof (intptr_t));
- FcMemAlloc (FC_MEM_CHARSET, (fcs->num + 1) * sizeof (intptr_t));
- fcs->leaves_offset = FcPtrToOffset (fcs, leaves);
+ if (!leaves)
+ return FcFalse;
- if (!fcs->num)
- numbers = malloc (sizeof (FcChar16));
- else
- numbers = realloc (numbers, (fcs->num + 1) * sizeof (FcChar16));
- if (!numbers)
- return FcFalse;
+ if (fcs->num)
+ FcMemFree (FC_MEM_CHARSET, fcs->num * sizeof (intptr_t));
+ FcMemAlloc (FC_MEM_CHARSET, (fcs->num + 1) * sizeof (intptr_t));
+ fcs->leaves_offset = FcPtrToOffset (fcs, leaves);
- if (fcs->num)
- FcMemFree (FC_MEM_CHARSET, fcs->num * sizeof (FcChar16));
- FcMemAlloc (FC_MEM_CHARSET, (fcs->num + 1) * sizeof (FcChar16));
- fcs->numbers_offset = FcPtrToOffset (fcs, numbers);
+ if (!fcs->num)
+ numbers = malloc ((capacity + 8) * sizeof (FcChar16));
+ else
+ numbers = realloc (numbers, (capacity + 8) * sizeof (FcChar16));
+ if (!numbers)
+ return FcFalse;
+ if (fcs->num)
+ FcMemFree (FC_MEM_CHARSET, fcs->num * sizeof (FcChar16));
+ FcMemAlloc (FC_MEM_CHARSET, (fcs->num + 1) * sizeof (FcChar16));
+ fcs->numbers_offset = FcPtrToOffset (fcs, numbers);
+ }
memmove (leaves + pos + 1, leaves + pos,
(fcs->num - pos) * sizeof (*leaves));
_______________________________________________
Fontconfig mailing list
Fontconfig@xxxxxxxxxxxxxxxxxxxxx
http://lists.freedesktop.org/mailman/listinfo/fontconfig