diff options
author | Dieter Verfaillie <dieterv@optionexplicit.be> | 2013-10-17 17:26:10 +0200 |
---|---|---|
committer | Colin Walters <walters@verbum.org> | 2013-10-17 15:03:26 -0400 |
commit | 65a0fa4c4e005047af7ec029c733bed4bd80292f (patch) | |
tree | fb76a7fec121c54827b0eaef946d25e1732464af /giscanner/sourcescanner.c | |
parent | 69d2fe30289795b3daf099a5f84ff9216dc6ed44 (diff) | |
download | gobject-introspection-65a0fa4c4e005047af7ec029c733bed4bd80292f.tar.gz |
giscanner: speed up SourceScanner().parse_files()
Was looking around a bit and noticed about 2/3 of
g-ir-scanner time is spent in SourceScanner().parse_files().
Some profiling quickly shows most of that 2/3 is used
by gi_source_scanner_add_symbol() where it creates a whole
bunch of GFile instances just to compare paths and throw
them away again. With this a scanner instance now maintains
a hash table of GFile instances instead of a list of file
names, so comparing those paths can be reduced to a fast
g_hash_table_contains() call.
This makes "g-ir-scanner <whole_bunch_of_options> --output Gtk-3.0.gir"
complete in about 10 seconds on my box instead of about
30 seconds (both best of 3 runs).
https://bugzilla.gnome.org/show_bug.cgi?id=710320
Diffstat (limited to 'giscanner/sourcescanner.c')
-rw-r--r-- | giscanner/sourcescanner.c | 45 |
1 files changed, 14 insertions, 31 deletions
diff --git a/giscanner/sourcescanner.c b/giscanner/sourcescanner.c index 90db2946..70eca8d0 100644 --- a/giscanner/sourcescanner.c +++ b/giscanner/sourcescanner.c @@ -25,11 +25,11 @@ #include <gio/gio.h> GISourceSymbol * -gi_source_symbol_new (GISourceSymbolType type, const gchar *filename, int line) +gi_source_symbol_new (GISourceSymbolType type, GFile *file, int line) { GISourceSymbol *s = g_slice_new0 (GISourceSymbol); s->ref_count = 1; - s->source_filename = g_strdup (filename); + s->source_filename = g_file_get_parse_name (file); s->type = type; s->line = line; return s; @@ -47,8 +47,9 @@ ctype_free (GISourceType * type) GISourceSymbol * gi_source_symbol_copy (GISourceSymbol * symbol) { + GFile *source_file = g_file_new_for_path (symbol->source_filename); GISourceSymbol *new_symbol = gi_source_symbol_new (symbol->type, - symbol->source_filename, + source_file, symbol->line); new_symbol->ident = g_strdup (symbol->ident); @@ -213,11 +214,13 @@ gi_source_scanner_new (void) scanner = g_slice_new0 (GISourceScanner); scanner->typedef_table = g_hash_table_new_full (g_str_hash, g_str_equal, - g_free, NULL); + g_free, NULL); scanner->struct_or_union_or_enum_table = g_hash_table_new_full (g_str_hash, g_str_equal, - g_free, (GDestroyNotify)gi_source_symbol_unref); + g_free, (GDestroyNotify)gi_source_symbol_unref); + scanner->files = g_hash_table_new_full (g_file_hash, (GEqualFunc)g_file_equal, + g_object_unref, NULL); return scanner; } @@ -232,7 +235,7 @@ gi_source_comment_free (GISourceComment *comment) void gi_source_scanner_free (GISourceScanner *scanner) { - g_free (scanner->current_filename); + g_object_unref (scanner->current_file); g_hash_table_destroy (scanner->typedef_table); g_hash_table_destroy (scanner->struct_or_union_or_enum_table); @@ -242,8 +245,7 @@ gi_source_scanner_free (GISourceScanner *scanner) g_slist_foreach (scanner->symbols, (GFunc)gi_source_symbol_unref, NULL); g_slist_free (scanner->symbols); - g_list_foreach (scanner->filenames, (GFunc)g_free, NULL); - g_list_free (scanner->filenames); + g_hash_table_unref (scanner->files); } @@ -266,29 +268,12 @@ void gi_source_scanner_add_symbol (GISourceScanner *scanner, GISourceSymbol *symbol) { - gboolean found_filename = FALSE; - GList *l; - GFile *current_file; - - g_assert (scanner->current_filename); - current_file = g_file_new_for_path (scanner->current_filename); + g_assert (scanner->current_file); - for (l = scanner->filenames; l != NULL; l = l->next) - { - GFile *file = g_file_new_for_path (l->data); - - if (g_file_equal (file, current_file)) - { - found_filename = TRUE; - g_object_unref (file); - break; - } - g_object_unref (file); - } - - if (found_filename || scanner->macro_scan) + if (scanner->macro_scan || g_hash_table_contains (scanner->files, scanner->current_file)) scanner->symbols = g_slist_prepend (scanner->symbols, - gi_source_symbol_ref (symbol)); + gi_source_symbol_ref (symbol)); + g_assert (symbol->source_filename != NULL); switch (symbol->type) @@ -308,8 +293,6 @@ gi_source_scanner_add_symbol (GISourceScanner *scanner, default: break; } - - g_object_unref (current_file); } GSList * |