[Nautilus-list] Optimizations



I've spent today pouring over some nautilus profiles. Here are a couple of 
patches that help, that i'd like to discuss.

Index: libnautilus-private/nautilus-icon-container.c
===================================================================
RCS file: /cvs/gnome/nautilus/libnautilus-private/nautilus-icon-container.c,v
retrieving revision 1.267
diff -u -p -r1.267 nautilus-icon-container.c
--- libnautilus-private/nautilus-icon-container.c	7 Mar 2002 19:36:02 -0000	1.267
+++ libnautilus-private/nautilus-icon-container.c	11 Mar 2002 02:55:18 -0000
@@ -785,7 +785,6 @@ lay_down_one_line (NautilusIconContainer
 	double height_above, height_below, x, width;
 
 	g_assert (NAUTILUS_IS_ICON_CONTAINER (container));
-	g_assert (line_end == NULL || g_list_first (line_start) == g_list_first (line_end));
 	g_assert (y != NULL);
 
 	/* Compute the total height above and below the baseline. */


These two g_list_first calls ended up at over 1% in my profiles. Is it ok 
to just remove the assert, on the assumption that since they haven't 
triggered yet the code is probably ok.

Another problem is that nautilus_file_get_display_name() gets called a 
*lot*, since sorting of views are done my display name. Since 
get_display_name needs to do a non-trivial amount of work these days i 
added a cache to it. I also changed the file-comparison code to not need 
copies of the display name when sorting. This moved g_utf8_validate from 
the nr one spot in the profile (6-10%) to 0.11%. 

I'm not sure this is the best way though. What do you think Darin?

Index: libnautilus-private/nautilus-directory-async.c
===================================================================
RCS file: /cvs/gnome/nautilus/libnautilus-private/nautilus-directory-async.c,v
retrieving revision 1.181
diff -u -p -r1.181 nautilus-directory-async.c
--- libnautilus-private/nautilus-directory-async.c	6 Mar 2002 00:40:28 -0000	1.181
+++ libnautilus-private/nautilus-directory-async.c	11 Mar 2002 02:55:15 -0000
@@ -2776,6 +2776,7 @@ link_info_done (NautilusDirectory *direc
 	file->details->activation_uri = g_strdup (uri);
 	file->details->display_name = g_strdup (name);
 	file->details->custom_icon_uri = g_strdup (icon);
+ 	nautilus_file_clear_cached_display_name (file);
 
 	nautilus_directory_async_state_changed (directory);
 }
Index: libnautilus-private/nautilus-file-private.h
===================================================================
RCS file: /cvs/gnome/nautilus/libnautilus-private/nautilus-file-private.h,v
retrieving revision 1.42
diff -u -p -r1.42 nautilus-file-private.h
--- libnautilus-private/nautilus-file-private.h	4 Mar 2002 19:53:08 -0000	1.42
+++ libnautilus-private/nautilus-file-private.h	11 Mar 2002 02:55:16 -0000
@@ -53,6 +53,11 @@ struct NautilusFileDetails
 	NautilusDirectory *directory;
 	char *relative_uri;
 
+	/* Cached version of the display name, guaranteed UTF8 safe.
+	 * This is used a lot for sorting views.
+	 */
+	char *cached_display_name;
+
 	GnomeVFSFileInfo *info;
 	GnomeVFSResult get_info_error;
 
@@ -132,6 +137,8 @@ gboolean      nautilus_file_get_date    
 							    NautilusDateType        date_type,
 							    time_t                 *date);
 void          nautilus_file_updated_deep_count_in_progress (NautilusFile           *file);
+void          nautilus_file_clear_cached_display_name      (NautilusFile           *file);
+
 
 /* Compare file's state with a fresh file info struct, return FALSE if
  * no change, update file and return TRUE if the file info contains
Index: libnautilus-private/nautilus-file.c
===================================================================
RCS file: /cvs/gnome/nautilus/libnautilus-private/nautilus-file.c,v
retrieving revision 1.284
diff -u -p -r1.284 nautilus-file.c
--- libnautilus-private/nautilus-file.c	10 Mar 2002 18:20:09 -0000	1.284
+++ libnautilus-private/nautilus-file.c	11 Mar 2002 02:55:17 -0000
@@ -101,11 +101,13 @@ static guint signals[LAST_SIGNAL];
 
 static GHashTable *symbolic_links;
 
-static char *   nautilus_file_get_owner_as_string (NautilusFile      *file,
-						   gboolean           include_real_name);
-static char *   nautilus_file_get_type_as_string  (NautilusFile      *file);
-static gboolean update_info_and_name              (NautilusFile      *file,
-						   GnomeVFSFileInfo  *info);
+static char *   nautilus_file_get_owner_as_string     (NautilusFile     *file,
+						       gboolean          include_real_name);
+static char *   nautilus_file_get_type_as_string      (NautilusFile     *file);
+static gboolean update_info_and_name                  (NautilusFile     *file,
+						       GnomeVFSFileInfo *info);
+static char *   nautilus_file_get_display_name_nocopy (NautilusFile     *file);
+
 
 GNOME_CLASS_BOILERPLATE (NautilusFile, nautilus_file,
 			 GtkObject, GTK_TYPE_OBJECT)
@@ -411,6 +413,7 @@ finalize (GObject *object)
 
 	nautilus_directory_unref (directory);
 	g_free (file->details->relative_uri);
+	g_free (file->details->cached_display_name);
 	if (file->details->info != NULL) {
 		gnome_vfs_file_info_unref (file->details->info);
 	}
@@ -1234,6 +1237,7 @@ update_info_internal (NautilusFile *file
 				(file->details->directory, file);
 			g_free (file->details->relative_uri);
 			file->details->relative_uri = new_relative_uri;
+			nautilus_file_clear_cached_display_name (file);
 			nautilus_directory_end_file_name_change
 				(file->details->directory, file, node);
 		}
@@ -1281,6 +1285,7 @@ nautilus_file_update_name (NautilusFile 
 			(file->details->directory, file);
 		g_free (file->details->relative_uri);
 		file->details->relative_uri = gnome_vfs_escape_string (name);
+		nautilus_file_clear_cached_display_name (file);
 		nautilus_directory_end_file_name_change
 			(file->details->directory, file, node);
 	} else {
@@ -1524,8 +1529,8 @@ compare_by_display_name (NautilusFile *f
 	gboolean sort_last_1, sort_last_2;
 	int compare;
 
-	name_1 = nautilus_file_get_display_name (file_1);
-	name_2 = nautilus_file_get_display_name (file_2);
+	name_1 = nautilus_file_get_display_name_nocopy (file_1);
+	name_2 = nautilus_file_get_display_name_nocopy (file_2);
 
 	sort_last_1 = strchr (SORT_LAST_CHARACTERS, name_1[0]) != NULL;
 	sort_last_2 = strchr (SORT_LAST_CHARACTERS, name_2[0]) != NULL;
@@ -1538,9 +1543,6 @@ compare_by_display_name (NautilusFile *f
 		compare = eel_strcoll (name_1, name_2);
 	}
 
-	g_free (name_1);
-	g_free (name_2);
-
 	return compare;
 }
 
@@ -2208,16 +2210,28 @@ make_valid_utf8 (char *name)
 	return g_string_free (string, FALSE);
 }
 
-char *
-nautilus_file_get_display_name (NautilusFile *file)
+void
+nautilus_file_clear_cached_display_name (NautilusFile *file)
+{
+	g_free (file->details->cached_display_name);
+	file->details->cached_display_name = NULL;
+}
+
+static char *
+nautilus_file_get_display_name_nocopy (NautilusFile *file)
 {
 	char *name, *utf8_name;
+	gboolean broken_filenames;
+	gboolean validated = FALSE;
 
 	if (file == NULL) {
 		return NULL;
 	}
 
 	g_return_val_if_fail (NAUTILUS_IS_FILE (file), NULL);
+
+	if (file->details->cached_display_name != NULL)
+		return file->details->cached_display_name;
 	
  	if (file->details->got_link_info && file->details->display_name != NULL) {
  		name = g_strdup (file->details->display_name);
@@ -2237,19 +2251,35 @@ nautilus_file_get_display_name (Nautilus
 			 * validate as good UTF-8.
 			 */
 			if (has_local_path (file)) {
-				if (have_broken_filenames ()
-				    || !g_utf8_validate (name, -1, NULL)) {
+				broken_filenames = have_broken_filenames ();
+				if (broken_filenames || !g_utf8_validate (name, -1, NULL)) {
 					utf8_name = g_locale_to_utf8 (name, -1, NULL, NULL, NULL);
 					if (utf8_name != NULL) {
 						g_free (name);
 						name = utf8_name;
+						validated = TRUE;
+						return name; /* Guaranteed to be correct utf8 here */
 					}
+				} else if (!broken_filenames) {
+					/* name was valid, no need to re-validate */
+					validated = TRUE;
 				}
 			}
 		}
 	}
 
-	return make_valid_utf8 (name);
+	if (!validated) {
+		name = make_valid_utf8 (name);
+	}
+	
+	file->details->cached_display_name = name;
+	return name;
+}
+
+char *
+nautilus_file_get_display_name (NautilusFile *file)
+{
+	return g_strdup (nautilus_file_get_display_name_nocopy (file));
 }
 
 char *

With this and some patches to other modules the top of the profile when 
loading several large directories is:

00080040 194      0.981483    __malloc                /lib/i686/libc-2.2.4.so 
00016964 198      1.00172     g_hash_table_lookup     /mnt/hdb2/gnome/head/INSTALL/lib/libglib-2.0.so.0.0.0 
00008b7c 210      1.06243     g_closure_invoke        /mnt/hdb2/gnome/head/INSTALL/lib/libgobject-2.0.so.0.0.0 
0002582c 210      1.06243     g_type_check_is_value_type /mnt/hdb2/gnome/head/INSTALL/lib/libgobject-2.0.so.0.0.0 
00085a40 211      1.06749     index                   /lib/i686/libc-2.2.4.so 
00023c9c 213      1.07761     g_type_is_a             /mnt/hdb2/gnome/head/INSTALL/lib/libgobject-2.0.so.0.0.0 
00027220 216      1.09279     g_value_init            /mnt/hdb2/gnome/head/INSTALL/lib/libgobject-2.0.so.0.0.0 
00080d20 235      1.18891     chunk_free              /lib/i686/libc-2.2.4.so 
0001e640 237      1.19903     gnome_canvas_group_draw /mnt/hdb2/gnome/head/INSTALL/lib/libgnomecanvas-2.so.0.0.0 
000274f4 260      1.31539     g_value_unset           /mnt/hdb2/gnome/head/INSTALL/lib/libgobject-2.0.so.0.0.0 
000802b0 306      1.54811     chunk_alloc             /lib/i686/libc-2.2.4.so 
00027c2c 314      1.58859     g_value_type_compatible /mnt/hdb2/gnome/head/INSTALL/lib/libgobject-2.0.so.0.0.0 
00025d4c 351      1.77578     g_type_value_table_peek /mnt/hdb2/gnome/head/INSTALL/lib/libgobject-2.0.so.0.0.0 
0001a8e4 460      2.32723     g_signal_emit_valist    /mnt/hdb2/gnome/head/INSTALL/lib/libgobject-2.0.so.0.0.0 
0001b9a4 469      2.37276     signal_emit_unlocked_R  /mnt/hdb2/gnome/head/INSTALL/lib/libgobject-2.0.so.0.0.0 
00007d80 482      2.43853     __pthread_mutex_unlock  /lib/i686/libpthread-0.9.so 
00007cb0 548      2.77244     __pthread_mutex_lock    /lib/i686/libpthread-0.9.so 
0000aea0 574      2.90398     __pthread_alt_lock      /lib/i686/libpthread-0.9.so 
0000ad00 655      3.31377     __pthread_alt_unlock    /lib/i686/libpthread-0.9.so 
00024eac 668      3.37954     g_type_check_instance_cast /mnt/hdb2/gnome/head/INSTALL/lib/libgobject-2.0.so.0.0.0 
00085c44 701      3.54649     strcoll                 /lib/i686/libc-2.2.4.so 
000249fc 953      4.82141     g_type_check_instance_is_a /mnt/hdb2/gnome/head/INSTALL/lib/libgobject-2.0.so.0.0.0 

Seems hard to improve this by doing nautilus changes.

-- 
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
 Alexander Larsson                                            Red Hat, Inc 
                   alexl redhat com    alla lysator liu se 
He's a lonely day-dreaming cat burglar searching for his wife's true killer. 
She's a brilliant winged stripper with someone else's memories. They fight 
crime! 





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