Skip to content

Commit

Permalink
Performance improvements due to conditional parsing of IO data depend…
Browse files Browse the repository at this point in the history
…ing on selected fields.

On my machine, this gives a ~20% improvement in htop process time use with the default config.
  • Loading branch information
hishamhm committed May 24, 2013
1 parent 5c2d84a commit 6cfa9e0
Show file tree
Hide file tree
Showing 7 changed files with 61 additions and 6 deletions.
2 changes: 2 additions & 0 deletions ChangeLog
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ What's new in version 1.0.3

* Performance improvements
(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

Expand Down
5 changes: 4 additions & 1 deletion ColumnsPanel.c
Original file line number Diff line number Diff line change
Expand Up @@ -122,11 +122,14 @@ void ColumnsPanel_update(Panel* super) {
// FIXME: this is crappily inefficient
free(this->settings->pl->fields);
this->settings->pl->fields = (ProcessField*) malloc(sizeof(ProcessField) * (size+1));
this->settings->pl->flags = 0;
for (int i = 0; i < size; i++) {
char* text = ((ListItem*) Panel_get(super, i))->value;
int j = ColumnsPanel_fieldNameToIndex(text);
if (j > 0)
if (j > 0) {
this->settings->pl->fields[i] = j;
this->settings->pl->flags |= Process_fieldFlags[j];
}
}
this->settings->pl->fields[size] = 0;
}
Expand Down
31 changes: 31 additions & 0 deletions Process.c
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,12 @@ in the source distribution for its full text.
#include "IOPriority.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
#define Process_isKernelThread(_process) (_process->pgrp == 0)
#endif
Expand Down Expand Up @@ -201,6 +207,31 @@ const char *Process_fieldNames[] = {
"*** 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[] = {
"", " PID ", "Command ", "S ", " PPID ", " PGRP ", " SESN ",
" TTY ", " TPGID ", "- ", "- ", "- ", "- ", "- ",
Expand Down
8 changes: 8 additions & 0 deletions Process.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,12 @@ in the source distribution for its full text.
#include "IOPriority.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
#define Process_isKernelThread(_process) (_process->pgrp == 0)
#endif
Expand Down Expand Up @@ -155,6 +161,8 @@ typedef struct Process_ {

extern const char *Process_fieldNames[];

extern const int Process_fieldFlags[];

extern const char *Process_fieldTitles[];


Expand Down
18 changes: 13 additions & 5 deletions ProcessList.c
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,7 @@ typedef struct ProcessList_ {
unsigned long long int usedSwap;
unsigned long long int freeSwap;
int flags;
ProcessField* fields;
ProcessField sortKey;
int direction;
Expand Down Expand Up @@ -235,8 +236,10 @@ ProcessList* ProcessList_new(UsersTable* usersTable, Hashtable* pidWhiteList) {
this->fields = calloc(sizeof(ProcessField), LAST_PROCESSFIELD+1);
// TODO: turn 'fields' into a Vector,
// (and ProcessFields into proper objects).
this->flags = 0;
for (int i = 0; defaultHeaders[i]; i++) {
this->fields[i] = defaultHeaders[i];
this->fields[i] |= Process_fieldFlags[defaultHeaders[i]];
}
this->sortKey = PERCENT_CPU;
this->direction = 1;
Expand Down Expand Up @@ -738,7 +741,8 @@ static bool ProcessList_processEntries(ProcessList* this, const char* dirname, P
ProcessList_processEntries(this, subdirname, process, period, tv);

#ifdef HAVE_TASKSTATS
ProcessList_readIoFile(process, dirname, name, now);
if (this->flags & PROCESS_FLAG_IO)
ProcessList_readIoFile(process, dirname, name, now);
#endif

if (! ProcessList_readStatmFile(process, dirname, name))
Expand All @@ -750,7 +754,8 @@ static bool ProcessList_processEntries(ProcessList* this, const char* dirname, P
unsigned long long int lasttimes = (process->utime + process->stime);
if (! ProcessList_readStatFile(process, dirname, name, command))
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;
process->percent_cpu = MAX(MIN(percent_cpu, cpus*100.0), 0.0);
if (isnan(process->percent_cpu)) process->percent_cpu = 0.0;
Expand All @@ -764,15 +769,18 @@ static bool ProcessList_processEntries(ProcessList* this, const char* dirname, P
process->user = UsersTable_getRef(this->usersTable, process->st_uid);

#ifdef HAVE_OPENVZ
ProcessList_readOpenVZData(process, dirname, name);
if (this->flags & PROCESS_FLAG_OPENVZ)
ProcessList_readOpenVZData(process, dirname, name);
#endif

#ifdef HAVE_CGROUP
ProcessList_readCGroupFile(process, dirname, name);
if (this->flags & PROCESS_FLAG_CGROUP)
ProcessList_readCGroupFile(process, dirname, name);
#endif

#ifdef HAVE_VSERVER
ProcessList_readVServerData(process, dirname, name);
if (this->flags & PROCESS_FLAG_VSERVER)
ProcessList_readVServerData(process, dirname, name);
#endif

if (! ProcessList_readCmdlineFile(process, dirname, name))
Expand Down
1 change: 1 addition & 0 deletions ProcessList.h
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,7 @@ typedef struct ProcessList_ {
unsigned long long int usedSwap;
unsigned long long int freeSwap;

int flags;
ProcessField* fields;
ProcessField sortKey;
int direction;
Expand Down
2 changes: 2 additions & 0 deletions Settings.c
Original file line number Diff line number Diff line change
Expand Up @@ -82,11 +82,13 @@ static bool Settings_read(Settings* this, char* fileName, int cpuCount) {
char** ids = String_split(trim, ' ', &nIds);
free(trim);
int i, j;
this->pl->flags = 0;
for (j = 0, i = 0; i < LAST_PROCESSFIELD && ids[i]; i++) {
// This "+1" is for compatibility with the older enum format.
int id = atoi(ids[i]) + 1;
if (id > 0 && id < LAST_PROCESSFIELD) {
this->pl->fields[j] = id;
this->pl->flags |= Process_fieldFlags[id];
j++;
}
}
Expand Down

0 comments on commit 6cfa9e0

Please sign in to comment.