Realloc called too often in FcCharSetPutLeaf

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



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

[Index of Archives]     [Fedora Fonts]     [Fedora Users]     [Fedora Cloud]     [Kernel]     [Fedora Packaging]     [Fedora Desktop]     [PAM]     [Gimp Graphics Editor]     [Yosemite News]

  Powered by Linux