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