Optimierte Cee Funktion exec Fragment
StartSeite | Neues | TestSeite | ForumSeite | Teilnehmer | Kategorien | Index | Hilfe | Einstellungen | Ändern
Folgende Funktion ist aus dem Linux Kernel. Das Original findet man in linux/fs/binfmt_script.c
- Situation
- Eine Datei soll ausgeführt werden. Nach dem Befragen der entsprechenden Magischen Zahlen wurde festgestellt, dass es sich bei der Datei um ein Script handelt. In der ersten Zeile eines Scriptes findet sich eine Zeichenfolge, die angibt mit welchem Interpreter das Script aufgerufen werden soll:
| #! /pfad/interpreter [argument]\n |
|
|
- Aufgabe
- Der Interpreter und das optionale Argument sollen gefunden werden.
| static int load_script(struct linux_binprm *bprm, struct pt_regs *regs)
{
char *cp, *i_name, *i_arg;
char interp[BINPRM_BUF_SIZE];
if ((bprm->buf[0] != '#') || (bprm->buf[1] != '!') || (bprm->sh_bang))
return -ENOEXEC;
/* SETUP SKIPPED */
bprm->buf[BINPRM_BUF_SIZE - 1] = '\0';
if ((cp = strchr(bprm->buf, '\n')) == NULL)
cp = bprm->buf+BINPRM_BUF_SIZE-1;
*cp = '\0';
while (cp > bprm->buf) {
cp--;
if ((*cp == ' ') || (*cp == '\t'))
*cp = '\0';
else
break;
}
for (cp = bprm->buf+2; (*cp == ' ') || (*cp == '\t'); cp++);
if (*cp == '\0')
return -ENOEXEC; /* No interpreter name found */
i_name = cp;
i_arg = 0;
for ( ; *cp && (*cp != ' ') && (*cp != '\t'); cp++)
/* nothing */ ;
while ((*cp == ' ') || (*cp == '\t'))
*cp++ = '\0';
if (*cp)
i_arg = cp;
strcpy (interp, i_name_start);
/* EXEC SKIPPED */
} |
|
|
Es ist oben keinerlei Konzept, Schema oder System erkennbar. Es wurde einfach von oben nach unten in der Reihenfolge der Gedanken und Notwendigkeiten jeweils eine Konstruktion gewählt, die das punktuell anstehende Problem löst, ohne im voraus zu denken und auch ohne zu rekapitulieren. Als Folge der Konzeptlosigkeit werden die zu parsenden Daten mehrfach gelesen.
Folgende Variante ist eine OptimierungPerKonzeption?. Es wurde ein wiederverwendbares und skalierbares Parse-Konzept überlegt. Desweiteren wurde auf möglichst wenige Lese-, Schreib- und Test-Aktionen als zu erreichendes Ziel geachtet.
Das Konzept [lautet so ... bitte ausfüllen].
[Zwischenraum-]Daten-Zwischenraum-Daten-Zwischenraum-...
z= gerade ungerade gerade ungerade gerade ...
Etwa halber Code-Umfang und wahrscheinlich doppelt so schnell:
| static int load_script(struct linux_binprm *bprm, struct pt_regs *regs)
{
int z;
char * cp;
char interp[BINPRM_BUF_SIZE];
char * ocp= interp;
char * i_arg;
char * i_name;
char * i_name_start;
if ((bprm->buf[0] != '#') || (bprm->buf[1] != '!') || (bprm->sh_bang))
return -ENOEXEC;
/* ... */
for (z=0,*((cp=bprm->buf+2)+127-2)='\n'; 1; ++cp) {
if (*cp==' '||*cp=='\t') {
if (z&1) {
if (*ocp=0, z>=3) break;
if (++z==2) i_name=ocp;
++ocp;
}
continue;
}
if (z==0) i_name_start=cp, ++z;
if (z==2) i_arg= cp, ++z;
if (*cp!='\n') { *ocp++ = *cp; continue; }
if (*ocp=0, z==1) i_name=ocp;
break;
}
if (!z || *i_name_start==0) return -ENOEXEC;
while (--i_name>i_name_start && *i_name!='/');
if (*i_name=='/') ++i_name;
/* ... */
}
/*
Man achte auf die 'Zustands-Maschine z'.
z ungerade/gerade
z-Paare 0..1 2..3
switch(z) bei vielen Args; oder *Array
i_name wird als i_name_end verwendet
*/ |
|
|
--HelmutSchellong
Der Code soll jedoch nur zur Demonstration des Konzeptes dienen und weicht in Details von der Originalimplementierung ab.
- Macht [...] das Programmierkonzept unerkennbar? - Nein! Eine kleine Erklärung für hilflose Nasen, wie mich, wäre aber schon fein. -- DavidSchmitt
KategorieOptimierung KategorieSchellong
StartSeite | Neues | TestSeite | ForumSeite | Teilnehmer | Kategorien | Index | Hilfe | Einstellungen | Ändern
Text dieser Seite ändern (zuletzt geändert: 10. September 2003 1:02 (diff))