diff options
author | KAMEZAWA Hiroyuki <kamezawa.hiroyu@jp.fujitsu.com> | 2012-03-23 18:02:54 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2012-03-23 19:58:42 -0400 |
commit | 1ac101a5d675aca2426c5cd460c73fb95acb8391 (patch) | |
tree | 5d993fde0c5e67de97c0d9ffac54163f06fc90c9 /lib | |
parent | 59a32e2ce5eb809967cac4e718bc527beca83c59 (diff) |
procfs: add num_to_str() to speed up /proc/stat
== stat_check.py
num = 0
with open("/proc/stat") as f:
while num < 1000 :
data = f.read()
f.seek(0, 0)
num = num + 1
==
perf shows
20.39% stat_check.py [kernel.kallsyms] [k] format_decode
13.41% stat_check.py [kernel.kallsyms] [k] number
12.61% stat_check.py [kernel.kallsyms] [k] vsnprintf
10.85% stat_check.py [kernel.kallsyms] [k] memcpy
4.85% stat_check.py [kernel.kallsyms] [k] radix_tree_lookup
4.43% stat_check.py [kernel.kallsyms] [k] seq_printf
This patch removes most of calls to vsnprintf() by adding num_to_str()
and seq_print_decimal_ull(), which prints decimal numbers without rich
functions provided by printf().
On my 8cpu box.
== Before patch ==
[root@bluextal test]# time ./stat_check.py
real 0m0.150s
user 0m0.026s
sys 0m0.121s
== After patch ==
[root@bluextal test]# time ./stat_check.py
real 0m0.055s
user 0m0.022s
sys 0m0.030s
[akpm@linux-foundation.org: remove incorrect comment, use less statck in num_to_str(), move comment from .h to .c, simplify seq_put_decimal_ull()]
[andrea@betterlinux.com: avoid breaking the ABI in /proc/stat]
Signed-off-by: KAMEZAWA Hiroyuki <kamezawa.hiroyu@jp.fujitsu.com>
Signed-off-by: Andrea Righi <andrea@betterlinux.com>
Cc: Eric Dumazet <eric.dumazet@gmail.com>
Cc: Glauber Costa <glommer@parallels.com>
Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Paul Turner <pjt@google.com>
Cc: Russell King <rmk@arm.linux.org.uk>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'lib')
-rw-r--r-- | lib/vsprintf.c | 20 |
1 files changed, 20 insertions, 0 deletions
diff --git a/lib/vsprintf.c b/lib/vsprintf.c index 38e612e66da5..385c40291cdb 100644 --- a/lib/vsprintf.c +++ b/lib/vsprintf.c | |||
@@ -212,6 +212,26 @@ char *put_dec(char *buf, unsigned long long num) | |||
212 | } | 212 | } |
213 | } | 213 | } |
214 | 214 | ||
215 | /* | ||
216 | * Convert passed number to decimal string. | ||
217 | * Returns the length of string. On buffer overflow, returns 0. | ||
218 | * | ||
219 | * If speed is not important, use snprintf(). It's easy to read the code. | ||
220 | */ | ||
221 | int num_to_str(char *buf, int size, unsigned long long num) | ||
222 | { | ||
223 | char tmp[21]; /* Enough for 2^64 in decimal */ | ||
224 | int idx, len; | ||
225 | |||
226 | len = put_dec(tmp, num) - tmp; | ||
227 | |||
228 | if (len > size) | ||
229 | return 0; | ||
230 | for (idx = 0; idx < len; ++idx) | ||
231 | buf[idx] = tmp[len - idx - 1]; | ||
232 | return len; | ||
233 | } | ||
234 | |||
215 | #define ZEROPAD 1 /* pad with zero */ | 235 | #define ZEROPAD 1 /* pad with zero */ |
216 | #define SIGN 2 /* unsigned/signed long */ | 236 | #define SIGN 2 /* unsigned/signed long */ |
217 | #define PLUS 4 /* show plus */ | 237 | #define PLUS 4 /* show plus */ |