Possible _gdk_pixmap_create speedup




Currently _gdk_pixmap_create_from_xpm() does a hash table lookup for each
pixel's color, which seems pretty inefficient to me.

For most xpms, which use 1 character for each pixel, we could use a table
lookup. For the rest, we could possibly cache the last pixel.

(For Glade, which creates ~65 icons when started, this results in a small but
noticeable improvement.)

Damon

Experimental patch:


--- gdkpixmap.c.orig	Sat Jan 23 11:27:30 1999
+++ gdkpixmap.c	Mon Feb 22 15:31:39 1999
@@ -435,13 +435,14 @@
   GdkVisual *visual;
   GdkGC *gc = NULL;
   GdkColor tmp_color;
-  gint width, height, num_cols, cpp, n, ns, cnt, xcnt, ycnt, wbytes;
+  gint width, height, num_cols, cpp, n, i, cnt, xcnt, ycnt, wbytes;
   gchar *buffer, pixel_str[32];
   gchar *name_buf;
-  _GdkPixmapColor *color = NULL, *fallbackcolor = NULL;
+  _GdkPixmapColor *color = NULL, *last_color = NULL, *fallbackcolor = NULL;
   _GdkPixmapColor *colors = NULL;
   gulong index;
   GHashTable *color_hash = NULL;
+  guchar color_table[256];
   _GdkPixmapInfo *color_info = NULL;
   
   if ((window == NULL) && (colormap == NULL))
@@ -469,7 +470,10 @@
       return NULL;
     }
   
-  color_hash = g_hash_table_new (g_str_hash, g_str_equal);
+  if (cpp == 1)
+    memset (color_table, 0, 256);
+  else
+    color_hash = g_hash_table_new (g_str_hash, g_str_equal);
   
   if (transparent_color == NULL)
     {
@@ -526,7 +530,11 @@
       if (color_info)
 	color_info->pixels[cnt] = color->color.pixel;
       
-      g_hash_table_insert (color_hash, color->color_string, color);
+      if (cpp == 1)
+	color_table[(gint)color->color_string[0]] = cnt;
+      else
+	g_hash_table_insert (color_hash, color->color_string, color);
+
       if (cnt == 0)
 	fallbackcolor = color;
     }
@@ -554,6 +562,8 @@
     }
   
   wbytes = width * cpp;
+  pixel_str[0] = '\0';
+  last_color = NULL;
   for (ycnt = 0; ycnt < height; ycnt++)
     {
       buffer = (*get_buf) (op_body, handle);
@@ -567,12 +577,28 @@
       
       for (n = 0, cnt = 0, xcnt = 0; n < wbytes; n += cpp, xcnt++)
 	{
-	  strncpy (pixel_str, &buffer[n], cpp);
-	  pixel_str[cpp] = 0;
-	  ns = 0;
-	  
-	  color = g_hash_table_lookup (color_hash, pixel_str);
-	  
+	  if (cpp == 1)
+	    color = &colors[color_table[(gint)buffer[n]]];
+	  else
+	    {
+	      for (i = 0; i < cpp; i++)
+		if (buffer[n + i] != pixel_str[i])
+		  break;
+
+	      /* Check if we matched the last color. */
+	      if (i == cpp)
+		color = last_color;
+	      else
+		{
+		  for (i = 0; i < cpp; i++)
+		    pixel_str[i] = buffer[n + i];
+		  pixel_str[cpp] = '\0';
+
+		  last_color = color = g_hash_table_lookup (color_hash,
+							    pixel_str);
+		}
+	    }
+
 	  if (!color) /* screwed up XPM file */
 	    color = fallbackcolor;



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