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; }