svn commit: trunk/busybox/libbb

vda at busybox.net vda at busybox.net
Tue Jun 19 13:46:27 UTC 2007


Author: vda
Date: 2007-06-19 06:46:24 -0700 (Tue, 19 Jun 2007)
New Revision: 18853

Log:
top,ps: reduce CPU usage in decimal conversion (optional)

   text    data     bss     dec     hex filename
 734651    3040   14416  752107   b79eb busybox_old
 734751    3040   14416  752207   b7a4f busybox_unstripped



Modified:
   trunk/busybox/libbb/Config.in
   trunk/busybox/libbb/procps.c


Changeset:
Modified: trunk/busybox/libbb/Config.in
===================================================================
--- trunk/busybox/libbb/Config.in	2007-06-19 12:11:20 UTC (rev 18852)
+++ trunk/busybox/libbb/Config.in	2007-06-19 13:46:24 UTC (rev 18853)
@@ -26,6 +26,13 @@
 	  2                   3.0                5088
 	  3 (smallest)        5.1                4912
 
+config FEATURE_FAST_TOP
+	bool "Faster /proc scanning code (+100 bytes)"
+	default n
+	help
+	  This option makes top (and ps) ~20% faster (or 20% less CPU hungry),
+	  but code size is slightly bigger.
+
 config FEATURE_ETC_NETWORKS
 	bool "Support for /etc/networks"
 	default n

Modified: trunk/busybox/libbb/procps.c
===================================================================
--- trunk/busybox/libbb/procps.c	2007-06-19 12:11:20 UTC (rev 18852)
+++ trunk/busybox/libbb/procps.c	2007-06-19 13:46:24 UTC (rev 18853)
@@ -107,6 +107,28 @@
 	free(sp);
 }
 
+#if ENABLE_FEATURE_FAST_TOP
+/* We cut a lot of corners here for speed */
+static unsigned long fast_strtoul_10(char *str, char **endptr)
+{
+	char c;
+	unsigned long n = *str - '0';
+
+	while ((c = *++str) != ' ')
+		n = n*10 + (c - '0');
+
+	*endptr = str + 1; /* We skip trailing space! */
+	return n;
+}
+static char *skip_fields(char *str, int count)
+{
+	do {
+		str = skip_non_whitespace(str); str++;
+	} while (--count);
+	return str;
+}
+#endif
+
 void BUG_comm_size(void);
 procps_status_t* procps_scan(procps_status_t* sp, int flags)
 {
@@ -160,7 +182,9 @@
 
 		if (flags & PSSCAN_STAT) {
 			char *cp;
+#if !ENABLE_FEATURE_FAST_TOP
 			unsigned long vsz, rss;
+#endif
 			int tty;
 
 			/* see proc(5) for some details on this */
@@ -175,6 +199,8 @@
 			if (sizeof(sp->comm) < 16)
 				BUG_comm_size();
 			sscanf(buf, "%*s (%15c", sp->comm);
+
+#if !ENABLE_FEATURE_FAST_TOP
 			n = sscanf(cp+2,
 				"%c %u "               /* state, ppid */
 				"%u %u %d %*s "        /* pgid, sid, tty, tpgid */
@@ -197,6 +223,8 @@
 				&rss);
 			if (n != 10)
 				break;
+			sp->vsz = vsz >> 10; /* vsize is in bytes and we want kb */
+			sp->rss = rss >> 10;
 
 			sp->tty_str[0] = '?';
 			/* sp->tty_str[1] = '\0'; - done by memset */
@@ -204,6 +232,31 @@
 				snprintf(sp->tty_str, sizeof(sp->tty_str), "%u,%u",
 					(tty >> 8) & 0xfff, /* major */
 					(tty & 0xff) | ((tty >> 12) & 0xfff00));
+#else
+/* This costs ~100 bytes more but makes top faster by 20%
+ * If you run 10000 processes, this may be important for you */
+			cp += 2;
+			sp->state[0] = *cp++; cp++;
+			sp->ppid = fast_strtoul_10(cp, &cp);
+			sp->pgid = fast_strtoul_10(cp, &cp);
+			sp->sid = fast_strtoul_10(cp, &cp);
+			sp->tty_str[0] = '?';
+			/* sp->tty_str[1] = '\0'; - done by memset */
+			tty = fast_strtoul_10(cp, &cp);
+			if (tty) /* tty field of "0" means "no tty" */
+				snprintf(sp->tty_str, sizeof(sp->tty_str), "%u,%u",
+					(tty >> 8) & 0xfff, /* major */
+					(tty & 0xff) | ((tty >> 12) & 0xfff00));
+			cp = skip_fields(cp, 6); /* tpgid, flags, min_flt, cmin_flt, maj_flt, cmaj_flt */
+			sp->utime = fast_strtoul_10(cp, &cp);
+			sp->stime = fast_strtoul_10(cp, &cp);
+			cp = skip_fields(cp, 3); /* cutime, cstime, priority */
+			tasknice = fast_strtoul_10(cp, &cp);
+			cp = skip_fields(cp, 3); /* timeout, it_real_value, start_time */
+			sp->vsz = fast_strtoul_10(cp, &cp) >> 10; /* vsize is in bytes and we want kb */
+			sp->rss = fast_strtoul_10(cp, &cp) >> 10;
+#endif
+
 			if (sp->vsz == 0 && sp->state[0] != 'Z')
 				sp->state[1] = 'W';
 			else
@@ -215,8 +268,6 @@
 			else
 				sp->state[2] = ' ';
 
-			sp->vsz = vsz >> 10; /* vsize is in bytes and we want kb */
-			sp->rss = rss >> 10;
 		}
 
 		if (flags & PSSCAN_CMD) {




More information about the busybox-cvs mailing list