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/scannerlexer.l | |
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/scannerlexer.l')
-rw-r--r-- | giscanner/scannerlexer.l | 26 |
1 files changed, 17 insertions, 9 deletions
diff --git a/giscanner/scannerlexer.l b/giscanner/scannerlexer.l index 2e3d0ab7..91f50cb9 100644 --- a/giscanner/scannerlexer.l +++ b/giscanner/scannerlexer.l @@ -51,6 +51,7 @@ static void parse_trigraph (GISourceScanner *scanner); static void process_linemarks (GISourceScanner *scanner); static int check_identifier (GISourceScanner *scanner, const char *); static int parse_ignored_macro (void); +static void print_error (GISourceScanner *scanner); %} %option nounput @@ -211,7 +212,7 @@ stringtext ([^\\\"])|(\\.) "\""{stringtext}*"\"" { return STRING; } "L\""{stringtext}*"\"" { return STRING; } -. { if (yytext[0]) fprintf(stderr, "%s:%d: unexpected character `%c'\n", scanner->current_filename, lineno, yytext[0]); } +. { print_error(scanner); } %% @@ -238,9 +239,7 @@ parse_comment (GISourceScanner *scanner) * Store GTK-Doc comment blocks, * starts with one '/' followed by exactly two '*' and not followed by a '/' */ - if (!g_list_find_custom (scanner->filenames, - scanner->current_filename, - (GCompareFunc)g_strcmp0)) { + if (!g_hash_table_contains (scanner->files, scanner->current_file)) { skip = TRUE; } else { string = g_string_new (yytext); @@ -269,10 +268,9 @@ parse_comment (GISourceScanner *scanner) comment = g_slice_new (GISourceComment); comment->comment = g_string_free (string, FALSE); comment->line = comment_lineno; - comment->filename = g_strdup(scanner->current_filename); + comment->filename = g_file_get_parse_name (scanner->current_file); - scanner->comments = g_slist_prepend (scanner->comments, - comment); + scanner->comments = g_slist_prepend (scanner->comments, comment); } else { /* * Ignore all other comment blocks @@ -324,8 +322,8 @@ process_linemarks (GISourceScanner *scanner) filename = g_strcompress (escaped_filename); real = g_realpath (filename); if (real) { - g_free (scanner->current_filename); - scanner->current_filename = real; + g_object_unref (scanner->current_file); + scanner->current_file = g_file_new_for_path (real); } else { g_free (real); } @@ -399,3 +397,13 @@ parse_trigraph (GISourceScanner *scanner) } g_strfreev (items); } + +static void +print_error (GISourceScanner *scanner) +{ + if (yytext[0]) { + char *filename = g_file_get_parse_name (scanner->current_file); + fprintf(stderr, "%s:%d: unexpected character `%c'\n", filename, lineno, yytext[0]); + g_free (filename); + } +} |