Commit 6cfa9e0b authored by Hisham Muhammad's avatar Hisham Muhammad
Browse files

Performance improvements due to conditional parsing of IO data depending on selected fields.

On my machine, this gives a ~20% improvement in htop process time use with the default config.
parent 5c2d84ab
...@@ -3,6 +3,8 @@ What's new in version 1.0.3 ...@@ -3,6 +3,8 @@ What's new in version 1.0.3
* Performance improvements * Performance improvements
(thanks to Jann Horn) (thanks to Jann Horn)
* Further performance improvements due to conditional parsing
of IO data depending on selected fields.
What's new in version 1.0.2 What's new in version 1.0.2
......
...@@ -122,11 +122,14 @@ void ColumnsPanel_update(Panel* super) { ...@@ -122,11 +122,14 @@ void ColumnsPanel_update(Panel* super) {
// FIXME: this is crappily inefficient // FIXME: this is crappily inefficient
free(this->settings->pl->fields); free(this->settings->pl->fields);
this->settings->pl->fields = (ProcessField*) malloc(sizeof(ProcessField) * (size+1)); this->settings->pl->fields = (ProcessField*) malloc(sizeof(ProcessField) * (size+1));
this->settings->pl->flags = 0;
for (int i = 0; i < size; i++) { for (int i = 0; i < size; i++) {
char* text = ((ListItem*) Panel_get(super, i))->value; char* text = ((ListItem*) Panel_get(super, i))->value;
int j = ColumnsPanel_fieldNameToIndex(text); int j = ColumnsPanel_fieldNameToIndex(text);
if (j > 0) if (j > 0) {
this->settings->pl->fields[i] = j; this->settings->pl->fields[i] = j;
this->settings->pl->flags |= Process_fieldFlags[j];
}
} }
this->settings->pl->fields[size] = 0; this->settings->pl->fields[size] = 0;
} }
......
...@@ -45,6 +45,12 @@ in the source distribution for its full text. ...@@ -45,6 +45,12 @@ in the source distribution for its full text.
#include "IOPriority.h" #include "IOPriority.h"
#include <sys/types.h> #include <sys/types.h>
#define PROCESS_FLAG_IO 1
#define PROCESS_FLAG_IOPRIO 2
#define PROCESS_FLAG_OPENVZ 4
#define PROCESS_FLAG_VSERVER 8
#define PROCESS_FLAG_CGROUP 16
#ifndef Process_isKernelThread #ifndef Process_isKernelThread
#define Process_isKernelThread(_process) (_process->pgrp == 0) #define Process_isKernelThread(_process) (_process->pgrp == 0)
#endif #endif
...@@ -201,6 +207,31 @@ const char *Process_fieldNames[] = { ...@@ -201,6 +207,31 @@ const char *Process_fieldNames[] = {
"*** report bug! ***" "*** report bug! ***"
}; };
const int Process_fieldFlags[] = {
0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0,
#ifdef HAVE_OPENVZ
PROCESS_FLAG_OPENVZ, PROCESS_FLAG_OPENVZ,
#endif
#ifdef HAVE_VSERVER
PROCESS_FLAG_VSERVER,
#endif
#ifdef HAVE_TASKSTATS
PROCESS_FLAG_IO, PROCESS_FLAG_IO, PROCESS_FLAG_IO, PROCESS_FLAG_IO, PROCESS_FLAG_IO, PROCESS_FLAG_IO, PROCESS_FLAG_IO,
PROCESS_FLAG_IO, PROCESS_FLAG_IO, PROCESS_FLAG_IO,
#endif
#ifdef HAVE_CGROUP
PROCESS_FLAG_CGROUP,
#endif
PROCESS_FLAG_IOPRIO
};
const char *Process_fieldTitles[] = { const char *Process_fieldTitles[] = {
"", " PID ", "Command ", "S ", " PPID ", " PGRP ", " SESN ", "", " PID ", "Command ", "S ", " PPID ", " PGRP ", " SESN ",
" TTY ", " TPGID ", "- ", "- ", "- ", "- ", "- ", " TTY ", " TPGID ", "- ", "- ", "- ", "- ", "- ",
......
...@@ -24,6 +24,12 @@ in the source distribution for its full text. ...@@ -24,6 +24,12 @@ in the source distribution for its full text.
#include "IOPriority.h" #include "IOPriority.h"
#include <sys/types.h> #include <sys/types.h>
#define PROCESS_FLAG_IO 1
#define PROCESS_FLAG_IOPRIO 2
#define PROCESS_FLAG_OPENVZ 4
#define PROCESS_FLAG_VSERVER 8
#define PROCESS_FLAG_CGROUP 16
#ifndef Process_isKernelThread #ifndef Process_isKernelThread
#define Process_isKernelThread(_process) (_process->pgrp == 0) #define Process_isKernelThread(_process) (_process->pgrp == 0)
#endif #endif
...@@ -155,6 +161,8 @@ typedef struct Process_ { ...@@ -155,6 +161,8 @@ typedef struct Process_ {
extern const char *Process_fieldNames[]; extern const char *Process_fieldNames[];
extern const int Process_fieldFlags[];
extern const char *Process_fieldTitles[]; extern const char *Process_fieldTitles[];
......
...@@ -133,6 +133,7 @@ typedef struct ProcessList_ { ...@@ -133,6 +133,7 @@ typedef struct ProcessList_ {
unsigned long long int usedSwap; unsigned long long int usedSwap;
unsigned long long int freeSwap; unsigned long long int freeSwap;
int flags;
ProcessField* fields; ProcessField* fields;
ProcessField sortKey; ProcessField sortKey;
int direction; int direction;
...@@ -235,8 +236,10 @@ ProcessList* ProcessList_new(UsersTable* usersTable, Hashtable* pidWhiteList) { ...@@ -235,8 +236,10 @@ ProcessList* ProcessList_new(UsersTable* usersTable, Hashtable* pidWhiteList) {
this->fields = calloc(sizeof(ProcessField), LAST_PROCESSFIELD+1); this->fields = calloc(sizeof(ProcessField), LAST_PROCESSFIELD+1);
// TODO: turn 'fields' into a Vector, // TODO: turn 'fields' into a Vector,
// (and ProcessFields into proper objects). // (and ProcessFields into proper objects).
this->flags = 0;
for (int i = 0; defaultHeaders[i]; i++) { for (int i = 0; defaultHeaders[i]; i++) {
this->fields[i] = defaultHeaders[i]; this->fields[i] = defaultHeaders[i];
this->fields[i] |= Process_fieldFlags[defaultHeaders[i]];
} }
this->sortKey = PERCENT_CPU; this->sortKey = PERCENT_CPU;
this->direction = 1; this->direction = 1;
...@@ -738,7 +741,8 @@ static bool ProcessList_processEntries(ProcessList* this, const char* dirname, P ...@@ -738,7 +741,8 @@ static bool ProcessList_processEntries(ProcessList* this, const char* dirname, P
ProcessList_processEntries(this, subdirname, process, period, tv); ProcessList_processEntries(this, subdirname, process, period, tv);
#ifdef HAVE_TASKSTATS #ifdef HAVE_TASKSTATS
ProcessList_readIoFile(process, dirname, name, now); if (this->flags & PROCESS_FLAG_IO)
ProcessList_readIoFile(process, dirname, name, now);
#endif #endif
if (! ProcessList_readStatmFile(process, dirname, name)) if (! ProcessList_readStatmFile(process, dirname, name))
...@@ -750,7 +754,8 @@ static bool ProcessList_processEntries(ProcessList* this, const char* dirname, P ...@@ -750,7 +754,8 @@ static bool ProcessList_processEntries(ProcessList* this, const char* dirname, P
unsigned long long int lasttimes = (process->utime + process->stime); unsigned long long int lasttimes = (process->utime + process->stime);
if (! ProcessList_readStatFile(process, dirname, name, command)) if (! ProcessList_readStatFile(process, dirname, name, command))
goto errorReadingProcess; goto errorReadingProcess;
Process_updateIOPriority(process); if (this->flags & PROCESS_FLAG_IOPRIO)
Process_updateIOPriority(process);
float percent_cpu = (process->utime + process->stime - lasttimes) / period * 100.0; float percent_cpu = (process->utime + process->stime - lasttimes) / period * 100.0;
process->percent_cpu = MAX(MIN(percent_cpu, cpus*100.0), 0.0); process->percent_cpu = MAX(MIN(percent_cpu, cpus*100.0), 0.0);
if (isnan(process->percent_cpu)) process->percent_cpu = 0.0; if (isnan(process->percent_cpu)) process->percent_cpu = 0.0;
...@@ -764,15 +769,18 @@ static bool ProcessList_processEntries(ProcessList* this, const char* dirname, P ...@@ -764,15 +769,18 @@ static bool ProcessList_processEntries(ProcessList* this, const char* dirname, P
process->user = UsersTable_getRef(this->usersTable, process->st_uid); process->user = UsersTable_getRef(this->usersTable, process->st_uid);
#ifdef HAVE_OPENVZ #ifdef HAVE_OPENVZ
ProcessList_readOpenVZData(process, dirname, name); if (this->flags & PROCESS_FLAG_OPENVZ)
ProcessList_readOpenVZData(process, dirname, name);
#endif #endif
#ifdef HAVE_CGROUP #ifdef HAVE_CGROUP
ProcessList_readCGroupFile(process, dirname, name); if (this->flags & PROCESS_FLAG_CGROUP)
ProcessList_readCGroupFile(process, dirname, name);
#endif #endif
#ifdef HAVE_VSERVER #ifdef HAVE_VSERVER
ProcessList_readVServerData(process, dirname, name); if (this->flags & PROCESS_FLAG_VSERVER)
ProcessList_readVServerData(process, dirname, name);
#endif #endif
if (! ProcessList_readCmdlineFile(process, dirname, name)) if (! ProcessList_readCmdlineFile(process, dirname, name))
......
...@@ -113,6 +113,7 @@ typedef struct ProcessList_ { ...@@ -113,6 +113,7 @@ typedef struct ProcessList_ {
unsigned long long int usedSwap; unsigned long long int usedSwap;
unsigned long long int freeSwap; unsigned long long int freeSwap;
int flags;
ProcessField* fields; ProcessField* fields;
ProcessField sortKey; ProcessField sortKey;
int direction; int direction;
......
...@@ -82,11 +82,13 @@ static bool Settings_read(Settings* this, char* fileName, int cpuCount) { ...@@ -82,11 +82,13 @@ static bool Settings_read(Settings* this, char* fileName, int cpuCount) {
char** ids = String_split(trim, ' ', &nIds); char** ids = String_split(trim, ' ', &nIds);
free(trim); free(trim);
int i, j; int i, j;
this->pl->flags = 0;
for (j = 0, i = 0; i < LAST_PROCESSFIELD && ids[i]; i++) { for (j = 0, i = 0; i < LAST_PROCESSFIELD && ids[i]; i++) {
// This "+1" is for compatibility with the older enum format. // This "+1" is for compatibility with the older enum format.
int id = atoi(ids[i]) + 1; int id = atoi(ids[i]) + 1;
if (id > 0 && id < LAST_PROCESSFIELD) { if (id > 0 && id < LAST_PROCESSFIELD) {
this->pl->fields[j] = id; this->pl->fields[j] = id;
this->pl->flags |= Process_fieldFlags[id];
j++; j++;
} }
} }
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment