summaryrefslogtreecommitdiff
path: root/giscanner/scannerlexer.l
diff options
context:
space:
mode:
authorDieter Verfaillie <dieterv@optionexplicit.be>2013-10-17 17:26:10 +0200
committerColin Walters <walters@verbum.org>2013-10-17 15:03:26 -0400
commit65a0fa4c4e005047af7ec029c733bed4bd80292f (patch)
treefb76a7fec121c54827b0eaef946d25e1732464af /giscanner/scannerlexer.l
parent69d2fe30289795b3daf099a5f84ff9216dc6ed44 (diff)
downloadgobject-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.l26
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);
+ }
+}