Package: libstfl-dev
Version: 0.21-2+b1
Severity: normal
Tags: patch

When a form is modified with stfl_modify, STFL walks the whole widget tree
to check focus. But checking only modified part seems enough.

Without patch
$ time ./test 10000
../test 10000  1.28s user 0.00s system 99% cpu 1.287 total
$ time ./test 20000
../test 20000  5.63s user 0.00s system 99% cpu 5.633 total
$ time ./test 30000
../test 30000  19.36s user 0.01s system 99% cpu 19.374 total
$ perf record -o - ./test 10000 | perf report -i -
[ perf record: Woken up 1 times to write data ]
[ perf record: Captured and wrote 0.045 MB - (~1951 samples) ]
# Events: 1K cycles
#
# Overhead  Command      Shared Object               Symbol
# ........  .......  .................  ...................
#
    97.82%     test  test               [.] stfl_check_setfocus
     1.08%     test  test               [.] stfl_parser
     0.31%     test  libc-2.11.2.so     [.] wcscmp
     0.23%     test  libc-2.11.2.so     [.] wcscspn
     0.08%     test  test               [.] wcs...@plt
     0.08%     test  libc-2.11.2.so     [.] __GI___libc_free
     0.08%     test  test               [.] stfl_widget_new
     0.08%     test  libc-2.11.2.so     [.] _int_malloc
     0.08%     test  test               [.] stfl_modify
     0.08%     test  [kernel.kallsyms]  [k] __inc_zone_state
     0.08%     test  test               [.] mywcscspn
     0.01%     test  [kernel.kallsyms]  [k] copy_page_c
     0.00%     test  [kernel.kallsyms]  [k] x86_pmu_enable_all


#
# (For a higher level overview, try: perf report --sort comm,dso)
#

With patch
$ time ./test 10000
../test 10000  0.01s user 0.01s system 94% cpu 0.019 total
$ time ./test 100000
../test 100000  0.10s user 0.01s system 99% cpu 0.115 total
$ time ./test 1000000
../test 1000000  0.92s user 0.14s system 99% cpu 1.061 total
$ perf record -o - ./test 100000 | perf report -i -
[ perf record: Woken up 1 times to write data ]
[ perf record: Captured and wrote 0.009 MB - (~374 samples) ]
# Events: 99  cycles
#
# Overhead  Command         Shared Object                         Symbol
# ........  .......  ....................  .............................
#
    26.61%     test  test                  [.] mywcscspn
    13.53%     test  libc-2.11.2.so        [.] __GI_wcschr
    10.74%     test  libc-2.11.2.so        [.] wcscmp
     8.40%     test  test                  [.] stfl_widget_new
     7.71%     test  [kernel.kallsyms]     [k] clear_page_c
     5.75%     test  test                  [.] stfl_parser
     4.77%     test  libpthread-2.11.2.so  [.] __pthread_mutex_lock_internal
     4.16%     test  libc-2.11.2.so        [.] wcscspn
     3.82%     test  libc-2.11.2.so        [.] __GI___libc_free
     2.88%     test  test                  [.] read_type
     2.86%     test  libc-2.11.2.so        [.] memcpy
     1.91%     test  libc-2.11.2.so        [.] _int_malloc
     1.07%     test  libc-2.11.2.so        [.] __GI___libc_malloc
     0.96%     test  libc-2.11.2.so        [.] memset
     0.95%     test  test                  [.] wcs...@plt
     0.95%     test  [kernel.kallsyms]     [k] handle_mm_fault
     0.95%     test  test                  [.] stfl_widget_free
     0.95%     test  test                  [.] stfl_check_setfocus
     0.95%     test  [kernel.kallsyms]     [k] free_pages_prepare
     0.06%     test  [kernel.kallsyms]     [k] strnlen_user
     0.00%     test  [kernel.kallsyms]     [k] x86_pmu_enable_all


#
# (For a higher level overview, try: perf report --sort comm,dso)
#


-- System Information:
Debian Release: squeeze/sid
  APT prefers unstable
  APT policy: (500, 'unstable'), (1, 'experimental')
Architecture: amd64 (x86_64)

Kernel: Linux 2.6.37-rc3 (SMP w/4 CPU cores)
Locale: LANG=ja_JP.eucJP, LC_CTYPE=ja_JP.eucJP (charmap=EUC-JP)
Shell: /bin/sh linked to /bin/dash
#include <stfl.h>
#include <stdlib.h>

int main(int argc, char **argv)
{
    long c, i;
    struct stfl_form *form;

    if (argc < 2)
    {
	return 0;
    }

    c = strtol(argv[1], NULL, 0);
    form = stfl_create(L"list[l]");

    for (i = 0; i < c; ++i)
    {
	stfl_modify(form, L"l", L"append", L"listitem");
    }

    stfl_free(form);

    return 0;
}
--- stfl-0.21.orig/public.c     2008-05-17 13:51:40.000000000 +0000
+++ stfl-0.21/public.c  2010-11-24 07:15:24.521961589 +0000
@@ -300,19 +300,19 @@ void stfl_modify(struct stfl_form *f, co
        w = stfl_widget_by_name(f->root, name ? name : L"");
 
        if (!w)
-               goto finish;
+               goto unlock;
 
        mode = mode ? mode : L"";
 
        if (!wcscmp(mode, L"delete") && w != f->root) {
                stfl_widget_free(w);
-               goto finish;
+               goto unlock;
        }
 
        n = stfl_parser(text ? text : L"");
 
        if (!n)
-               goto finish;
+               goto unlock;
 
        if (!wcscmp(mode, L"replace")) {
                if (w == f->root)
@@ -329,6 +329,7 @@ void stfl_modify(struct stfl_form *f, co
                stfl_modify_insert(w, n->first_child);
                n->first_child = n->last_child = 0;
                stfl_widget_free(n);
+               n = w;
                goto finish;
        }
 
@@ -341,6 +342,7 @@ void stfl_modify(struct stfl_form *f, co
                stfl_modify_insert(w, n->first_child);
                n->first_child = n->last_child = 0;
                stfl_widget_free(n);
+               n = w;
                goto finish;
        }
 
@@ -353,6 +355,7 @@ void stfl_modify(struct stfl_form *f, co
                stfl_modify_append(w, n->first_child);
                n->first_child = n->last_child = 0;
                stfl_widget_free(n);
+               n = w;
                goto finish;
        }
 
@@ -365,6 +368,7 @@ void stfl_modify(struct stfl_form *f, co
                stfl_modify_before(w, n->first_child);
                n->first_child = n->last_child = 0;
                stfl_widget_free(n);
+               n = w;
                goto finish;
        }
 
@@ -377,11 +381,13 @@ void stfl_modify(struct stfl_form *f, co
                stfl_modify_after(w, n->first_child);
                n->first_child = n->last_child = 0;
                stfl_widget_free(n);
+               n = w;
                goto finish;
        }
 
 finish:
-       stfl_check_setfocus(f, f->root);
+       stfl_check_setfocus(f, n);
+unlock:
        pthread_mutex_unlock(&f->mtx);
        return;
 }

Reply via email to