Funktionsnamen beim Aufruf aus String lesen



  • Nein, nein, werden nur ca. 3 Einträge sein. Aber das ganze wird es dann 20 Mal geben. Es soll ein dynamisches Menü werden. Bin gerade dabei es anzupassen und lern auch schon was dabei, als doppelter Erfolg.



  • p1royal2 schrieb:

    Nein, nein, werden nur ca. 3 Einträge sein.

    Da sind es im Mittel nur 1.5 Stringvergleiche, das ist völlig in Ordnung. Aber falls es mehr als 10 oder 20 Einträge werden, würde ich anfangen, mir Gedanken darüber zu machen.
    🙂



  • also da ich bisher immer alles mit einem binären baum (oder ähnliche) gemacht hab, ist mir aufgefallen, dass man sowas auch sehr gut mit einer binären suche lösen kann, da man dadurch platz spart und die daten möglicherweise näher beisammen liegen, was das ganze schneller machen könnte.

    eignet sich besonders gut wenn die daten schon zur compile zeit vorliegen bzw. sich nicht oft ändern, da das einfügen ein bischen langsamer sein kann.

    lg lolo



  • noobLolo schrieb:

    also da ich bisher immer alles mit einem binären baum (oder ähnliche) gemacht hab, ist mir aufgefallen, dass man sowas auch sehr gut mit einer binären suche lösen kann, da man dadurch platz spart und die daten möglicherweise näher beisammen liegen, was das ganze schneller machen könnte.

    eignet sich besonders gut wenn die daten schon zur compile zeit vorliegen bzw. sich nicht oft ändern, da das einfügen ein bischen langsamer sein kann.

    Jup. Man braucht mindestens einen kompletten Stringvergleich, um zu schauen, ob der Eingabestring auch mit dem in der Tabelle übereinstimmt, und je nachdem, wieviele Strings in der Tabelle sind mehr oder weniger leider mehr oder weniger lange Stringvergleiche.
    Mit Glück kann für Compilezeitkonstante Tabellen man auch eine Funktion finden, die zufällig alle gültigen Strings auf eindeutige Arrayplätze verteilt, wie (suchstring[0]+3*suchstring[2])%17, dann würde sich das auf eine schnelle Rechnung und einen kompletten Stringvergleich reduzieren.



  • also performance lover legen doch die pointer gleich in einem array ab, auf das man mit einem numerischen index zugreifen kann oder 😉

    aber ja, eine hash tabelle eignet sich fast noch ein bischen besser

    lg lolo



  • Ups, ich Schelm habe ja eine Hashtabelle vorgestellt.



  • nachdem ich ne nacht darüber geschlafen hab, ist mir ein eindeutiger vorteil von mngbd's version aufgefallen. dadurch das der functions pointer zurückgegeben wird kann man ihn super in einer variablen zwischenspeichern und muß ihn nicht für jede verwendung wieder "suchen". dann hat der zum suchen verwendete algo nichtmehr so großen einfluss auf die performance.

    denke das wird auch in den mir bekannten versionen (windows(GetProcAddress), linux(dlsym)) so gelöst. beide geben den pointer zurück. 😉

    lg lolo



  • noobLolo schrieb:

    also performance lover legen doch die pointer gleich in einem array ab, auf das man mit einem numerischen index zugreifen kann oder 😉

    aber ja, eine hash tabelle eignet sich fast noch ein bischen besser

    lg lolo

    Auf jeden Fall ist die Hashtable die beste Lösung, weil wir ein kollisionsfreies Ausgangsszenario haben. Die Hashwertberechnung dürfte sogar flotter laufen als die Stringvergleicherei.
    Ach ja: Die deutsche Wiki hat dazu auch einen Artikel. Zum 'reinlesen vielleicht dann doch einfacher. 😉



  • pointercrash() schrieb:

    Auf jeden Fall ist die Hashtable die beste Lösung

    nun ja, also nur wenn die functionsnamen als string daher kommen;)

    pointercrash() schrieb:

    weil wir ein kollisionsfreies Ausgangsszenario haben.

    also das stimmt doch eher nicht oder 😕

    pointercrash() schrieb:

    Ach ja: Die deutsche Wiki hat dazu auch einen Artikel. Zum 'reinlesen vielleicht dann doch einfacher. 😉

    ja da hab ich auch schon geschaut aber da haben mir die bildchen gefehlt 😞

    lg lolo



  • p1royal2 schrieb:

    Nein, nein, werden nur ca. 3 Einträge sein.

    huch, hab ich grad vergessen dass es nur so wenig einträge sind 🤡

    lg lolo



  • In dem Ausgangsproblem bietet sich sogar eine sehr simple Hashtabelle an. 😉

    #include <stdio.h>
    
    typedef void (*fpointer_t)(void);
    typedef size_t hash_t;
    
    void Func1(void) { puts("eins"); }
    void Func2(void) { puts("zwei"); }
    
    hash_t hash(char *s)
    {
        return s[4] - '0' - 1;
    }
    
    fpointer_t lookup(fpointer_t *array, size_t size, char *name)
    {
        hash_t h = hash(name);
        return h < size ? array[h] : NULL;
    }
    
    int main(void)
    {
        fpointer_t array[] = {Func1, Func2};
    
        lookup(array, sizeof array, "Func1")();
        lookup(array, sizeof array, "Func2")();
    
        return 0;
    }
    

    Ich nehm für sowas als erstes immer einen Suchbaum, weil ich den fertig herumliegen hab, und man daran kaum was ändern oder gar nachdenken muss. Über ein elegantes Hashing denke ich (faul wie ich bin) erst nach, sobald der Baum zu langsam ist.
    🙂


Anmelden zum Antworten