On Thu, 2011-09-29 at 00:25 -0300, Leonardo Ferreira Fontenelle wrote:
> I'm trying to port a small Python GTK+ application to Vala. Overall, I
> have succeeded, with some very interesting performance gains. But in
> some cases the search may take a few seconds to finish, while the
> application reads data from the disk. I tried using an async method to
> keep the user interface responsive, but it didn't work: until the search
> is completed, the user can't even move the cursor in the text entry
> widget. What am I missing?
> 
> This is the relevant code; I hope the names are sufficiently
> descriptive.
> 
> 
> 
> public void on_search_entry_activate (Gtk.Entry entry) {
>       
>       this.timer.start();
>       
>       this.search_progressbar.show();
>       this.search_treeview.set_model(null);
>       this.search_results.clear(); // this is a Gtk.ListStore
>       
>       string entry_text = entry.get_text();
>       stdout.printf("Searching for: %s\n", entry_text);
>       string[] words = this.word_regex.split(entry_text);
>       this.search.begin(words, (obj, res) => {
>               this.search.end(res);
>               this.search_treeview.set_model(this.search_results);
>               this.timer.stop();
>               stdout.printf("%fs elapsed\n", this.timer.elapsed());
>               this.search_progressbar.hide();
>               this.search_progressbar.set_fraction(0.0);
>       });
> }
> 
> public async void search (string[] words) {
>       
>       Gee.TreeSet<int32> matches = get_matches (words);
>       
>       string code, title, inclusion_notes, exclusion_notes;
>       //user-relevant data
>       Gtk.TreeIter iter;
>       double fraction = 0.0;
>       double increment = 1.0 / matches.size;
        int i count = 0;
>       
>       foreach (int32 match in matches) {
>               get_node(match, out code, out title, out
>               inclusion_notes, out exclusion_notes);
Probably:
                yield get_node(match, out code, out title, out
                               inclusion_notes, out exclusion_notes);
>               this.search_results.append(out iter);
>               this.search_results.set(iter, 0, match, 1, code, 2,
>               title);
>               fraction += increment;
>               this.search_progressbar.set_fraction(fraction);
If get_node cannot be simply yielded:
                if ((++count % 1024) == 0) {
                        yield;
                }
>       }
> }
> 
> 
> 
> Thanks in advance, 
> 
> Leonardo Fontenelle

The problem is that by marking method async you move computation to
different part of code (in fact IIRC the returning of result in this
case) but not splitting it.

To get the speedout you should:

 - yield all I/O actions
 - split long computations by yield

Alternatively you can use threads but:

 - Threads are move heavyweight as they are system threads
 - Threads use real parallelism. It means that you can take advantage of
multi-core CPU
   - But IIRC the GDK/GTK+ is not thread-safe by default. You need to
add an additional calls to make it safe

Regards

Attachment: signature.asc
Description: This is a digitally signed message part

_______________________________________________
vala-list mailing list
[email protected]
http://mail.gnome.org/mailman/listinfo/vala-list

Reply via email to