mirror of https://github.com/xzeldon/htop.git
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.
This commit is contained in:
parent
5c2d84aba3
commit
6cfa9e0bf2
|
@ -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) {
|
||||||
// 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;
|
||||||
}
|
}
|
||||||
|
|
31
Process.c
31
Process.c
|
@ -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[] = {
|
||||||
"*** 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.
|
||||||
#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_ {
|
||||||
|
|
||||||
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_ {
|
||||||
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) {
|
||||||
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
|
||||||
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
|
||||||
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
|
||||||
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_ {
|
||||||
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) {
|
||||||
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++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue